/* $Header: pi_col.c,v 2.5 04/11/04 10:04:40 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME:                                                        */
/* ============                                                        */
/*                                                                     */
/* Author:                                                             */
/*                                                                     */
/* MODULE PURPOSE:                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include <typedefs.h>
#include <error.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <i_op.h>
#include <p_status.h>
#include <ramps.h>         /* needed for status.h */
#include <zone_config.h>   /* needed for status.h */
#include <zone_status.h>   /* needed for status.h */
#include <status.h>  /* pull in definition of Oven_Table */
#include <list_mgmt.h>
#include <run_ui.h>        /* for RunActiveOrPostTime() */
#include <math.h>
#include <exception.h>
#include <glp.h>
#include <clock_ui.h>
#include <keyboard.h>
#include <err_handler.h>
/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/

#include "proto.h"

/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/

/* the proto in hostutil.h needs too many other include files to begin including it here */
void StrNCpy(BIT8 *to_str,BIT8 *from_str,INT16 n);
void ResetSigPathState( void );  /* copied from "sig_ui.h"  */

/*****************************/
/*   LOCAL DEFINES           */
/*****************************/

#define MIN_OUTLET_PRES_CORRECTION    0   /*  0 psi @ 80 d/cm2 */
#define MAX_OUTLET_PRES_CORRECTION 8618   /* 10 psi @ 80 d/cm2 */

#define MIN_OUTLET_PRES_PSI     (    0 * DISPLAY_PSI_SCALE )
#define MIN_OUTLET_PRES_BAR     (    0 * DISPLAY_BAR_SCALE )
#define MIN_OUTLET_PRES_KPA     (    0 * DISPLAY_KPA_SCALE )

#define MAX_OUTLET_PRES_PSI         (   4 * DISPLAY_PSI_SCALE )
#define MAX_OUTLET_PRES_BAR ((INT32)(0.28 * DISPLAY_BAR_SCALE))
#define MAX_OUTLET_PRES_KPA         (  28 * DISPLAY_KPA_SCALE )

#define COL_MINIMUM_DIAM     (  50 * COLUMN_DIAM_SCALING )   /*  50 micron */
#define COL_MAXIMUM_DIAM     ( 750 * COLUMN_DIAM_SCALING )   /* 750 micron */

#define COL_MINIMUM_LEN      (   1 * COLUMN_LEN_SCALING  )   /*   1 meter  */
#define COL_MAXIMUM_LEN      ( 200 * COLUMN_LEN_SCALING  )   /* 200 meters */

#define COL_MINIMUM_FILM     (  1 * COLUMN_FILM_SCALING / 100 )  /*  .01micron */
#define COL_MAXIMUM_FILM     ( 50 * COLUMN_FILM_SCALING       )  /*  50 micron */

#define GET_OVEN_INIT_TEMP ( GetRampInitValue( &Oven_Temp_Info ) )

#define MAX_CALIB_LENGTH_DIFFERENCE  (   5 * COLUMN_LEN_SCALING  )   /*   5 meter  */
#define MAX_CALIB_DIAM_DIFFERENCE    (  20 * COLUMN_DIAM_SCALING )   /*  20 micron */

/*      pFRONT_INLET, pBACK_INLET must be same as in p_ui.h */
#define pFRONT_INLET         GetFrontInletPtr()
#define pBACK_INLET          GetBackInletPtr()

/*****************************/
/*   STATIC VARIABLES        */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/

/**begin_proto**/
#pragma SECTION PROG=rom3
/**end_proto**/

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

INT32 MilliSecsToRetTime( U_INT32 time )

/**end_proto**/
{
   return (INT32)time / 60;
}


/**begin_proto**/

U_INT32 RetTimeToMilliSecs ( INT32 time )

/**end_proto**/
{
   return time * 60;
}

/**begin_proto**/

UI_ERR ValidateRetTime ( INT32  time )

/**end_proto**/
{
    if ( time <      0 )   return PARAM_TOO_SMALL;
    if ( time > 999990 )   return PARAM_TOO_LARGE;

    return OK;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void SetNewFunnyConstFlowPostPres ( pCOLUMN_STATUS status )

/**end_proto**/
{

   U_INT16  oven_temp;
   U_INT16  init_pres;
   U_INT16  post_pres;
   U_INT16  max_pres;

   /* funny const flow mode */
   if ( Active_Wkfile.post_time > 0 )
   {
       oven_temp = Active_Wkfile.oven_temp.post_value;
   }
   else
   {
       oven_temp = GetOvenInitTemp();
   }


   init_pres = QuadWordMultiplyDivide(GetRampInitValue( status->Ramp_Info ),
                                      status->Ramp_Setpt.Ramp_Pres_Scaling,
                                      status->Dcm2_Per_IU );

   if (status->Config->Vacuum_Comp == ON)
   {
       post_pres = CalcPiFromPrevWVC( status, oven_temp, init_pres );
   }
   else
   {
       post_pres = CalcPiFromPrevWOVC( status, oven_temp, init_pres );
   }

   max_pres = GetSourceMaxPresIu( status );

   if ( post_pres > max_pres ) post_pres = max_pres;

   post_pres = QuadWordMultiplyDivide(post_pres,
                                      status->Dcm2_Per_IU,
                                      status->Ramp_Setpt.Ramp_Pres_Scaling );

   SetRampPostValue( status->Ramp_Info, post_pres );

}

/**begin_proto**/

void UpdateFunnyConstFlowPostPres ( pCOLUMN_STATUS status, U_INT16 new_post_temp )

/**end_proto**/
{

   U_INT16  oven_temp;
   U_INT16  post_pres;
   U_INT16  max_pres;

   /* funny const flow mode only */

   if (( !SourcePressureControlled( status ) ) ||
       (  status->Wkfile->Control_Mode != CONST_FLOW ))
   {
       /* if not funny const flow mode, exit out of here */

       return;
   }

   if ( Inst_Config.Pneu.Column_1.Source == Inst_Config.Pneu.Column_2.Source )
   {
        /* if both columns connected to same source, only calc for column 1 */

        if ( status->Position != 1 )  return;
   }


   if ( Active_Wkfile.post_time > 0 )
   {
       oven_temp = Active_Wkfile.oven_temp.post_value;
   }
   else
   {
       oven_temp = GetOvenInitTemp();
   }


   post_pres = QuadWordMultiplyDivide(GetRampPostValue( status->Ramp_Info ),
                                      status->Ramp_Setpt.Ramp_Pres_Scaling,
                                      status->Dcm2_Per_IU );

   post_pres = CalcPiRefFromPi ( status, oven_temp, post_pres );

   if (status->Config->Vacuum_Comp == ON)
   {
       post_pres = CalcPiFromPrevWVC( status, new_post_temp, post_pres );
   }
   else
   {
       post_pres = CalcPiFromPrevWOVC( status, new_post_temp, post_pres );
   }

   max_pres = GetSourceMaxPresIu( status );

   if ( post_pres > max_pres ) post_pres = max_pres;

   post_pres = QuadWordMultiplyDivide(post_pres,
                                      status->Dcm2_Per_IU,
                                      status->Ramp_Setpt.Ramp_Pres_Scaling );

   SetRampPostValue( status->Ramp_Info, post_pres );

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

RAMP_TYPE GetColumnRampType ( pCOLUMN_STATUS status )

/**end_proto**/
{

    return NativeRampType [          ColumnDefined( status )      ]
                          [ (U_INT8) GetColSrcType( status )   ]     /* <-- accounts for VI vent cap */
                          [ (U_INT8) status->Wkfile->Control_Mode ];

}

/**begin_proto**/

void VISamplingEndChk(pCOLUMN_STATUS col)

/**end_proto**/
{
     INT32 tym ;

/*   if (( GetColSourceType (col)) != VOLATILES_INLET) return ;  Not Needed b/c of tym=0 chk below !! */

     if ( ( GetColumnControlMode(col)==CONST_PRES ) || ( GetColumnControlMode(col)==CONST_FLOW ) ) return ;

     if ((tym =  GetVIInjTime( (GetColumnSource(col)==FRNT_INLET) ? pFRONT_INLET : pBACK_INLET ))==0) return ;

     if ( GetColPresInitTime(col) > tym ) return;

     ++tym ;
     ChangeColPresInitTime(col, tym );
/*   LogSetptChange( status->Position == 1 ? COL1_INIT_TIME : COL2_INIT_TIME, time, 0 ); done in ChangeColPresInitTime */
/*                 Note: SetptChg goes to GLP RUN_Log ONLY if in run or SCC_run !!                                     */
/*                       so, ...   we need SetNewException HERE to get a dialog time pop-up warning to user !!         */
     SetNewException(col->Position == 1 ? COL1_PNEU_TIME1_CONFLICT : COL2_PNEU_TIME1_CONFLICT, tym ,0 );
     ClearNewException (col->Position == 1 ? COL1_PNEU_TIME1_CONFLICT : COL2_PNEU_TIME1_CONFLICT );
}
/**begin_proto**/

COL_SOURCE_TYPE GetColSrcType(pCOLUMN_STATUS col)

/**end_proto**/

{
     COL_SOURCE_TYPE src;

     if ((src = GetColSourceType (col)) != VOLATILES_INLET) return src;

     if (  GetVISplitPort( (GetColumnSource(col)==FRNT_INLET) ? pFRONT_INLET : pBACK_INLET )  == CAPPED)
     return  PP_INLET;
     else
     return SS_INLET;
}




/**begin_proto**/

void ChangeRampType ( pCOLUMN_STATUS status )

/**end_proto**/
{
    COL_SOURCE_TYPE source;
    BIT8        defined;

    source  = GetColSrcType     ( status );
    defined = ColumnDefined        ( status );

    DisableRamp(  (pRAMPINFO)status->Ramp_Info );

    if ( NativeRampType [          defined                      ]
                        [ (U_INT8) source                       ]
                        [ (U_INT8) status->Wkfile->Control_Mode ] == FLOW_RAMP )
    {
         SetRampSetptPointer( (pRAMPINFO)status->Ramp_Info, (INT32 *)&status->Ramp_Setpt.Column_V_Flow );

         if ( GetRampType((pRAMPINFO)GetRampInfoPtr( status )) == PRESSURE_RAMP )
         {
#if 0
             if ( status->C3 != 0 )
             {
                  ConvertPresRampToFlowRamp( status );
             }
             else
#endif
             {
                  SetRampRate( status->Ramp_Info, 1, 0 );
                  SetRampRate( status->Ramp_Info, 2, 0 );
                  SetRampRate( status->Ramp_Info, 3, 0 );

                  SetRampFinalValue( status->Ramp_Info, 1, 0 );
                  SetRampFinalValue( status->Ramp_Info, 2, 0 );
                  SetRampFinalValue( status->Ramp_Info, 3, 0 );

                  SetRampFinalTime( status->Ramp_Info, 1, 0 );
                  SetRampFinalTime( status->Ramp_Info, 2, 0 );
                  SetRampFinalTime( status->Ramp_Info, 3, 0 );

                  SetRampPostValue( status->Ramp_Info, GetRampInitValue( status->Ramp_Info ) );

                  SetRampType( status->Ramp_Info, FLOW_RAMP );
             }
         };
    }
    else if ( NativeRampType [          defined                      ]
                             [ (U_INT8) source                       ]
                             [ (U_INT8) status->Wkfile->Control_Mode ] == PRESSURE_RAMP )
    {
         SetRampSetptPointer( (pRAMPINFO)status->Ramp_Info, (INT32 *)&status->Ramp_Setpt.Head_Pressure );

         if ( GetRampType((pRAMPINFO)GetRampInfoPtr( status )) == FLOW_RAMP )
         {
#if 0
             if ( status->C3 != 0 )
             {
                  ConvertFlowRampToPresRamp( status );
                  RangeCheckColumnPresRamps( status );
             }
             else
#endif
             {
                  SetRampRate( status->Ramp_Info, 1, 0 );
                  SetRampRate( status->Ramp_Info, 2, 0 );
                  SetRampRate( status->Ramp_Info, 3, 0 );

                  SetRampFinalValue( status->Ramp_Info, 1, 0 );
                  SetRampFinalValue( status->Ramp_Info, 2, 0 );
                  SetRampFinalValue( status->Ramp_Info, 3, 0 );

                  SetRampFinalTime( status->Ramp_Info, 1, 0 );
                  SetRampFinalTime( status->Ramp_Info, 2, 0 );
                  SetRampFinalTime( status->Ramp_Info, 3, 0 );

                  if (( !defined ) &&
                      ( status->Wkfile->Control_Mode == CONST_FLOW ) &&
                      ( SourcePressureControlled ( status ) ))
                  {
                       SetNewFunnyConstFlowPostPres( status );
                  }
                  else
                  {
                       SetRampPostValue( status->Ramp_Info, GetRampInitValue( status->Ramp_Info ) );
                  }

                  SetRampType( status->Ramp_Info, PRESSURE_RAMP );
             }
         };
    }

    switch ( status->Wkfile->Control_Mode )
    {
         case RAMP_FLOW:
         case RAMP_PRES:
                  EnableRamp(  (pRAMPINFO)status->Ramp_Info );
    };

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void UpdateColumnSourceSetpts( pCOLUMN_STATUS status, U_INT16 new_oven_temp )

/**end_proto**/
{

    U_INT16 pressure;
    U_INT16 ref_pres;
    U_INT16 max_pres;


    if ( !SourcePressureControlled ( status ) )
    {
         return;
    }


    if ( Inst_Config.Pneu.Column_1.Source == Inst_Config.Pneu.Column_2.Source )
    {
        /* if both columns connected to same source, only calc for column 1 */

        if ( status->Position != 1 )
        {
            return;
        }
    }



    if ((( status->Wkfile->Control_Mode == CONST_FLOW ) && ( status->Config->Defined )) ||
         ( status->Wkfile->Control_Mode == RAMP_FLOW ))
    {

         /* need to calculate pressre from flow */
         pressure = CalcPiFromVFlow ( QuadWordMultiplyDivide( status->Ramp_Setpt.Column_V_Flow,
                                                              status->IU_Scaling,
                                                              status->Ramp_Setpt.Ramp_Flow_Scaling ),
                                      new_oven_temp,
                                      GetNtpOutletPressure( status ),
                                      status );
    }
    else if (( status->Wkfile->Control_Mode == CONST_FLOW ) && ( !status->Config->Defined ))
    {
          ref_pres = QuadWordMultiplyDivide( GetRampInitValue( status->Ramp_Info ),
                                             status->Ramp_Setpt.Ramp_Pres_Scaling,
                                             status->Dcm2_Per_IU );

          if (status->Config->Vacuum_Comp == ON)
          {
              pressure = CalcPiFromPrevWVC( status, new_oven_temp, ref_pres );
          }
          else
          {
              pressure = CalcPiFromPrevWOVC( status, new_oven_temp, ref_pres );
          }
    }
    else if (( status->Wkfile->Control_Mode == CONST_PRES ) || ( status->Wkfile->Control_Mode == RAMP_PRES ))
    {
         pressure = QuadWordMultiplyDivide(GetRampInitValue( status->Ramp_Info ),
                                      status->Ramp_Setpt.Ramp_Pres_Scaling,
                                      status->Dcm2_Per_IU );
    }
    else
    {
        return ; /* should never happen */
    }

    max_pres = GetSourceMaxPresIu( status );

    if ( pressure > max_pres ) pressure = max_pres;

    switch ( status->Config->Source )
    {
       case FRNT_INLET:  UpdateInletPresSetpt( pressure, &Inst_Status.Pneu.Frnt_Inlet, status->Dcm2_Per_IU  );
                         break;
       case BACK_INLET:  UpdateInletPresSetpt( pressure, &Inst_Status.Pneu.Back_Inlet, status->Dcm2_Per_IU  );
                         break;
       case AUX_3:       UpdateAuxPresSetpt( pressure,  &Inst_Status.Pneu.Aux.Aux_3, status->Dcm2_Per_IU  );
                         break;
       case AUX_4:       UpdateAuxPresSetpt( pressure,  &Inst_Status.Pneu.Aux.Aux_4, status->Dcm2_Per_IU  );
                         break;
       case AUX_5:       UpdateAuxPresSetpt( pressure,  &Inst_Status.Pneu.Aux.Aux_5, status->Dcm2_Per_IU  );
                         break;
       default: ;
     }


}

/***********************************************************************/
/* FUNCTION: UpdateColumnStatus                                        */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  Modify the columns setpoints to match what they would     */
/*           be at a specified Pressure and temperature.               */
/*                                                                     */
/*                                                                     */
/* Called by the interface routines when control mode or configuration */
/* is changed.                                                         */
/*                                                                     */
/*  This routine is provided only to support run time programming of   */
/*  aux pressure zones.  It should not be used by anyone else.         */
/*                                                                     */
/*  WARNING: _Never_ update the workfile in this routine!              */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void UpdateColumnStatus ( U_INT16 pressure, U_INT16 oven_temp,  pCOLUMN_STATUS status, U_INT16 dcm2_per_iu )

/**end_proto**/
{
    U_INT16 Po;

    pressure = QuadWordMultiplyDivide( pressure, dcm2_per_iu, status->Dcm2_Per_IU );

    Po = GetNtpOutletPressure( status );

    status->Active_Pressure = pressure;

    switch ( status->Wkfile->Control_Mode )
    {
       case RAMP_FLOW:
       case CONST_FLOW:
                     if ( status->Config->Defined )
                     {
                          status->Ramp_Setpt.Column_V_Flow    = QuadWordMultiplyDivide (
                                                                       CalcVFlow ( status, oven_temp, pressure, Po ),
                                                                       status->Ramp_Setpt.Ramp_Flow_Scaling,
                                                                       status->IU_Scaling );
                     }
                     else
                     {
                         if (( status->Wkfile->Control_Mode == CONST_FLOW ) && SourcePressureControlled( status ))
                         {

                                status->Ramp_Setpt.Head_Pressure = CalcPiRefFromPi ( status, oven_temp,
                                                  (INT32)pressure * dcm2_per_iu / status->Ramp_Setpt.Ramp_Pres_Scaling );

                         }
                     }
                     break;

       case RAMP_PRES:
       case CONST_PRES:
                     status->Ramp_Setpt.Head_Pressure = QuadWordMultiplyDivide( pressure,
                                                                                status->Dcm2_Per_IU,
                                                                                status->Ramp_Setpt.Ramp_Pres_Scaling );

                     break;

    }  /* switch */

}

/***********************************************************************/
/* FUNCTION: UpdateColumnSetpts                                        */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  Modify the columns setpoints to match what they would     */
/*           be at a specified Pressure and temperature.               */
/*                                                                     */
/*                                                                     */
/* Called by the interface routines when control mode or configuration */
/* is changed.                                                         */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void UpdateColumnSetpts ( U_INT16 pressure, U_INT16 oven_temp,  pCOLUMN_STATUS status, U_INT16 p_scale )

/**end_proto**/
{
    U_INT16 Po;
    U_INT16 pres;
    U_INT32 flow;

    status->Active_Pressure = (INT32)pressure * p_scale / status->Dcm2_Per_IU;

    flow = 0;  /* for flexelint */

    Po = GetNtpOutletPressure( status );

    pres =  QuadWordMultiplyDivide( pressure,
                                    p_scale,
                                    status->Ramp_Setpt.Ramp_Pres_Scaling );

    if ( status->Config->Defined )
    {
         flow    = QuadWordMultiplyDivide( CalcVFlow ( status, oven_temp, pressure, Po ),
                                           status->Ramp_Setpt.Ramp_Flow_Scaling,
                                           status->IU_Scaling );
    }
    else
    {
        if (( status->Wkfile->Control_Mode == CONST_FLOW ) && SourcePressureControlled( status ))
        {

            pres = CalcPiRefFromPi ( status,
                                     oven_temp,
                                     (INT32)pressure * p_scale / status->Ramp_Setpt.Ramp_Pres_Scaling );

        }
    }


    switch( GetRampType( (pRAMPINFO)(status->Ramp_Info)) )
    {
    case PRESSURE_RAMP:  SetRampInitValue( (pRAMPINFO)(status->Ramp_Info), pres );
                         if ( Active_Wkfile.post_time == 0 )
                              if (( status->Wkfile->Control_Mode == CONST_FLOW ) && SourcePressureControlled( status ))
                              {
                                  SetNewFunnyConstFlowPostPres( status );
                              }
                              else
                              {
                                  SetRampPostValue( (pRAMPINFO)(status->Ramp_Info), pres );
                              }
                         break;

    case FLOW_RAMP:      SetRampInitValue( (pRAMPINFO)(status->Ramp_Info), flow );
                         if ( Active_Wkfile.post_time == 0 )
                              SetRampPostValue( (pRAMPINFO)(status->Ramp_Info), flow );
                         break;
    }

/* Copied from EOS! */
/* The next line is a fix for a bug that has been present ever since IQ!    */
/* UpdateColumnSourceSetpts uses the value in Column_V_Flow, but that value */
/*  is updated in UpdateColumnStatus, which hasn't been called yet. We call */
/*  it here to fix the problem, even though it will be called again shortly */
    UpdateColumnStatus ( pressure, oven_temp, status, p_scale );

    UpdateColumnSourceSetpts( status, GetOvenInitTemp() );

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void UpdateColumns ( U_INT16 pres_iu, U_INT16 oven_temp,  SOURCE_CONNECTION source, U_INT16 p_scale )

/**end_proto**/
{

     if ( Inst_Config.Pneu.Column_1.Source == source )
     {
         if ( RunActiveOrPostTime() == FALSE )
         {
             UpdateColumnSetpts(pres_iu, oven_temp, &Inst_Status.Pneu.Column_1, p_scale );
         }

         UpdateColumnStatus(pres_iu, oven_temp, &Inst_Status.Pneu.Column_1, p_scale );
         SlamSourceSetpt( &Inst_Status.Pneu.Column_1 );
     }

     if ( Inst_Config.Pneu.Column_2.Source == source )
     {
         if ( RunActiveOrPostTime() == FALSE )
         {
             UpdateColumnSetpts(pres_iu, oven_temp, &Inst_Status.Pneu.Column_2, p_scale );
         }

         UpdateColumnStatus(pres_iu, oven_temp, &Inst_Status.Pneu.Column_2, p_scale );
         SlamSourceSetpt( &Inst_Status.Pneu.Column_2 );
     }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void UpdateColumnsDamnIt ( U_INT16 pres_iu, U_INT16 oven_temp,  SOURCE_CONNECTION source, U_INT16 p_scale )

/**end_proto**/
{

     if ( Inst_Config.Pneu.Column_1.Source == source )
     {
         UpdateColumnSetpts(pres_iu, oven_temp, &Inst_Status.Pneu.Column_1, p_scale );
         UpdateColumnStatus(pres_iu, oven_temp, &Inst_Status.Pneu.Column_1, p_scale );
         SlamSourceSetpt( &Inst_Status.Pneu.Column_1 );
     }

     if ( Inst_Config.Pneu.Column_2.Source == source )
     {
         UpdateColumnSetpts(pres_iu, oven_temp, &Inst_Status.Pneu.Column_2, p_scale );
         UpdateColumnStatus(pres_iu, oven_temp, &Inst_Status.Pneu.Column_2, p_scale );
         SlamSourceSetpt( &Inst_Status.Pneu.Column_2 );
     }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void UpdateColumnsStatusOnly ( U_INT16 pres_iu, U_INT16 oven_temp,  SOURCE_CONNECTION source, U_INT16 p_scale )

/**end_proto**/
{

     if ( Inst_Config.Pneu.Column_1.Source == source )
     {
         UpdateColumnStatus(pres_iu, oven_temp, &Inst_Status.Pneu.Column_1, p_scale );
         SlamSourceSetpt( &Inst_Status.Pneu.Column_1 );
     }

     if ( Inst_Config.Pneu.Column_2.Source == source )
     {
         UpdateColumnStatus(pres_iu, oven_temp, &Inst_Status.Pneu.Column_2, p_scale );
         SlamSourceSetpt( &Inst_Status.Pneu.Column_2 );
     }


}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: to allow a flow controlled purged packed inlet to modify   */
/*          column setpoints related to total inlet flow.              */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void UpdateColumnFlowSetpt( U_INT32 flow, pCOLUMN_STATUS status, U_INT32 scaling )

/**end_proto**/
{

    status->Ramp_Setpt.Column_V_Flow = QuadWordMultiplyDivide( flow,
                                                               scaling,
                                                               status->Ramp_Setpt.Ramp_Flow_Scaling );

    if ( RunActiveOrPostTime() == FALSE )
    {
         SetRampInitValue( (pRAMPINFO)(status->Ramp_Info), status->Ramp_Setpt.Column_V_Flow );

         if ( Active_Wkfile.post_time == 0 )
             SetRampPostValue( (pRAMPINFO)(status->Ramp_Info), status->Ramp_Setpt.Column_V_Flow );
    }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ResetMiserMode( pCOLUMN_STATUS status )

/**end_proto**/
{

    /* miser mode is not available for inlets with undefined columns */

    switch ( GetColSourceType( status ) )
    {
        case SS_INLET:
        case CIS3_INLET:
        case CIS4_INLET:
        case VOLATILES_INLET:
                  if ( status->Config->Source == FRNT_INLET )  ChangeInletMiserMode ( OFF, &Inst_Status.Pneu.Frnt_Inlet );
                  else                                         ChangeInletMiserMode ( OFF, &Inst_Status.Pneu.Back_Inlet );
                  break;

        default:
                  break;
    }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void NewlyDefinedColumn( pCOLUMN_STATUS status )

/**end_proto**/
{

    U_INT16 pressure;
    U_INT16 oven_temp;
    U_INT16 Po;
    U_INT16 P_25C;

    oven_temp = GetOvenInitTemp();
    Po = GetNtpOutletPressure( status );

    ChangeRampType( status );

    if (( GetColSourceType( status ) == PP_INLET ) || ( GetColSourceType( status ) == SIMDIST_INLET )
                                                   || ( GetColSourceType( status ) == ACI_INLET ))
    {
         /* need to calculate pressre from flow */
         pressure = CalcPiFromVFlow ( QuadWordMultiplyDivide( status->Ramp_Setpt.Column_V_Flow,
                                                              status->IU_Scaling,
                                                              status->Ramp_Setpt.Ramp_Flow_Scaling ),
                                      oven_temp, Po, status );
    }
    else
    {
         if ( status->Wkfile->Control_Mode == CONST_FLOW )
         {
               P_25C = QuadWordMultiplyDivide( GetRampInitValue( (pRAMPINFO)status->Ramp_Info ),
                                               status->Ramp_Setpt.Ramp_Pres_Scaling,
                                               status->Dcm2_Per_IU );

               if (status->Config->Vacuum_Comp == ON)
               {
                    pressure = CalcPiFromPrevWVC( status, oven_temp, P_25C );
               }
               else
               {
                    pressure = CalcPiFromPrevWOVC( status, oven_temp, P_25C );
               }
         }
         else
         {
              /* need to calculate flow from pressure */

              pressure = QuadWordMultiplyDivide( status->Ramp_Setpt.Head_Pressure,
                                                 status->Ramp_Setpt.Ramp_Pres_Scaling,
                                                 status->Dcm2_Per_IU );
         }
    }

    UpdateColumnsDamnIt( pressure, oven_temp, status->Config->Source, status->Dcm2_Per_IU );

    if ( GetColSourceType ( status ) == SS_INLET )
    {
         NewlyDefinedColOnSsInlet ( (status->Config->Source == FRNT_INLET ) ?
                                             &Inst_Status.Pneu.Frnt_Inlet :
                                             &Inst_Status.Pneu.Back_Inlet  );
    }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void NewlyUnDefinedColumn( pCOLUMN_STATUS status )

/**end_proto**/
{

    U_INT16 Po;
    U_INT16 oven_temp;
    U_INT16 pressure;

    if (( GetColSourceType( status ) == PP_INLET ) || ( GetColSourceType( status ) == SIMDIST_INLET )
                                                   || ( GetColSourceType( status ) == ACI_INLET ))
    {
         if (( status->Wkfile->Control_Mode == RAMP_PRES ) ||
             ( status->Wkfile->Control_Mode == CONST_PRES ))
         {
              /* now an unsupported mode */
             (void)SetColumnControlMode( CONST_FLOW, status );
         }
    }
    else if ( GetColSourceType( status )== UNKNOWN_TYPE )
    {
         /* make sure any ramps go away, and any other funny behavior squelched */
         (void)SetColumnControlMode( CONST_FLOW, status );
    }
    else  /* some pressure controlled beastie */
    {
         if ( status->Wkfile->Control_Mode == RAMP_FLOW )
         {
              /* now an unsupported mode */
              status->Wkfile->Control_Mode = CONST_FLOW;

              /* intentionally fall through into the next if */
         }

         if ( status->Wkfile->Control_Mode == CONST_FLOW )
         {
            /* this is the hard case do it all here and bust out early */

            Po = GetNtpOutletPressure( status );
            oven_temp = GetOvenInitTemp();
            pressure = CalcPiFromVFlow( QuadWordMultiplyDivide( status->Ramp_Setpt.Column_V_Flow,
                                                                   status->IU_Scaling,
                                                                   status->Ramp_Setpt.Ramp_Flow_Scaling ),
                                       oven_temp, Po, status );


#if 0
            status->Ramp_Setpt.Head_Pressure = QuadWordMultiplyDivide( CalcPiRefFromPi ( status, oven_temp, pressure ),
                                                                             status->Ramp_Setpt.Ramp_Pres_Scaling,
                                                                             status->Dcm2_Per_IU );

            SetRampInitValue( (pRAMPINFO)(status->Ramp_Info), status->Ramp_Setpt.Head_Pressure );
#else
            UpdateColumnsDamnIt( pressure, oven_temp, status->Config->Source, status->Dcm2_Per_IU );
#endif


            ChangeRampType( status );
            ResetMiserMode( status );

            RescaleColumnFlows( status->IU_Scaling, 16384, status );
            status->IU_Scaling = 16384;

            return;
         }
    }

    ChangeRampType( status );
    ResetMiserMode( status );

    RescaleColumnFlows( status->IU_Scaling, 16384, status );
    status->IU_Scaling = 16384;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8  ColumnDimsKnown( pCOLUMN_STATUS  status )

/**end_proto**/
{

      if ((status->Config->Length != 0 )  &&
          (status->Config->Diam   != 0 ))
      {
            return TRUE;   /* both length and diam are known */
      }
      else
      {
            return FALSE;  /* one or both dimensions are unknown */
      }
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

INT32 GetColumnDiam( pCOLUMN_STATUS status )

/**end_proto**/
{
      return status->Config->Diam;
}

/**begin_proto**/

INT32 GetColumnLength( pCOLUMN_STATUS status )

/**end_proto**/
{
      return status->Config->Length;
}

/**begin_proto**/

INT32 GetColumnFilmThickness( pCOLUMN_STATUS status )

/**end_proto**/
{
      return status->Config->Film_Thickness;
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

char *DcGetColumnIdString( pCOLUMN_STATUS status )

/**end_proto**/
{
      return status->Config->ID_String;
}


/**begin_proto**/

UI_ERR DcSetColumnIdString( pCOLUMN_STATUS status, char *string)

/**end_proto**/
{
   char *dest;
   int  i;

      dest = status->Config->ID_String;

      for ( i = 0 ; i < ID_STRING_SIZE ; i++ )
      {
           *dest++ = *string;
           if ( *string++ == 0 ) break;
      }

      *dest = 0;

      return OK;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

INT32 GetColCalibMaxLengthDifference( void )

/**end_proto**/
{
     return MAX_CALIB_LENGTH_DIFFERENCE;
}

/**begin_proto**/

INT32 GetColCalibMaxDiamDifference ( void )

/**end_proto**/
{
     return MAX_CALIB_DIAM_DIFFERENCE;
}

/**begin_proto**/

INT32 GetColMinDiam ( void )

/**end_proto**/
{
     return COL_MINIMUM_DIAM;
}

/**begin_proto**/

INT32 GetColMaxDiam ( void )

/**end_proto**/
{
     return COL_MAXIMUM_DIAM;
}

/**begin_proto**/

INT32 GetColMinLen  ( void )

/**end_proto**/
{
     return COL_MINIMUM_LEN;
}

/**begin_proto**/

INT32 GetColMaxLen  ( void )

/**end_proto**/
{
     return COL_MAXIMUM_LEN;
}


/**begin_proto**/

INT32 GetColMinFilm ( void )

/**end_proto**/
{
     return COL_MINIMUM_FILM;
}

/**begin_proto**/

INT32 GetColMaxFilm ( void )

/**end_proto**/
{
     return COL_MAXIMUM_FILM;
}

/**begin_proto**/

UI_ERR ValidateCalibDiam ( pCOLUMN_STATUS status, INT32 Diam )

/**end_proto**/
{

     if ( Diam == 0 )               return OK;               /* diam is Undefined */
     if ( Diam < COL_MINIMUM_DIAM ) return PARAM_TOO_SMALL;   /* column to small */
     if ( Diam > COL_MAXIMUM_DIAM ) return PARAM_TOO_LARGE;   /* column to big   */

     if ( Diam > status->Config->Diam )
     {
        if (( Diam - status->Config->Diam) > MAX_CALIB_DIAM_DIFFERENCE ) return TEST_FAILED;
     }
     else
     {
        if (( status->Config->Diam - Diam ) > MAX_CALIB_DIAM_DIFFERENCE ) return TEST_FAILED;
     }

     return OK;                                              /* just fine       */
}


/**begin_proto**/

UI_ERR ValidateCalibLength( pCOLUMN_STATUS status, INT32 Length )

/**end_proto**/
{
     if ( Length == 0 )               return OK;                /* length Undefined */
     if ( Length <  COL_MINIMUM_LEN ) return PARAM_TOO_SMALL;   /* column to short */
     if ( Length >  COL_MAXIMUM_LEN ) return PARAM_TOO_LARGE;   /* column to long  */

     if ( Length > status->Config->Length )
     {
        if (( Length - status->Config->Length) > MAX_CALIB_LENGTH_DIFFERENCE ) return TEST_FAILED;
     }
     else
     {
        if (( status->Config->Length - Length ) > MAX_CALIB_LENGTH_DIFFERENCE ) return TEST_FAILED;
     }

     return OK;                                                 /* just fine       */
}


/**begin_proto**/

UI_ERR ValidateDiam ( INT32 Diam )

/**end_proto**/
{
     if ( Diam == 0 )               return OK;               /* diam is Undefined */
     if ( Diam < COL_MINIMUM_DIAM ) return PARAM_TOO_SMALL;   /* column to small */
     if ( Diam > COL_MAXIMUM_DIAM ) return PARAM_TOO_LARGE;   /* column to big   */
     return OK;                                              /* just fine       */
}


/**begin_proto**/

UI_ERR ValidateLength( INT32 Length )

/**end_proto**/
{
     if ( Length == 0 )               return OK;                /* length Undefined */
     if ( Length <  COL_MINIMUM_LEN ) return PARAM_TOO_SMALL;   /* column to short */
     if ( Length >  COL_MAXIMUM_LEN ) return PARAM_TOO_LARGE;   /* column to long  */
     return OK;                                                 /* just fine       */
}

/**begin_proto**/

UI_ERR ValidateFilmThickness ( INT32 thickness, pCOLUMN_STATUS status )

/**end_proto**/
{

     if ( thickness == 0 ) return OK;
     if ( thickness >= (status->Config->Diam*COLUMN_FILM_SCALING/2 )) return NOT_ALLOWED; /* no hole in column  */
     if ( thickness < COL_MINIMUM_FILM  ) return PARAM_TOO_SMALL;   /* thickness to thin  */
     if ( thickness > COL_MAXIMUM_FILM  ) return PARAM_TOO_LARGE;   /* thickness to thick */
     return OK;                                                     /* just fine       */
}

void   FixSmplgEndViolations( pCOLUMN_STATUS status )

{

      UI_ERR  error;
      pINLET_STATUS iptr;

      if ( DoingMethodInstall() == 0 )
      {
         VISamplingEndChk( status );
         error   = OK;
         switch ( status->Config->Source )
         {
             case FRNT_INLET: error = ValidateVIInjTime ( GetVIInjTime(pFRONT_INLET), iptr=pFRONT_INLET ) ;
                              break;

             case BACK_INLET: error = ValidateVIInjTime ( GetVIInjTime(pBACK_INLET ), iptr=pBACK_INLET  ) ;
                              break;

             default:
                              iptr    = pFRONT_INLET;   /* for flexelint */
                              error   = OK;
                              break;
         }

         #if 0
         switch ( error  )
         {
             case PURGE_TIME_CONFLICT:
                              FixVIPurgeTime(iptr);
                              break;

             case MISER_TIME_CONFLICT:
                              FixMiserTime(iptr);
                              break;

             default:
                              break;
         }
         #endif

         #if 0
             if (error == PURGE_TIME_CONFLICT) FixVIPurgeTime(iptr);

             if (error == MISER_TIME_CONFLICT) FixMiserTime(iptr);
         #endif

         #if 1
             if ((INT32)error == (INT32)PURGE_TIME_CONFLICT) FixVIPurgeTime(iptr);

             if ((INT32)error == (INT32)MISER_TIME_CONFLICT) FixMiserTime(iptr);
         #endif

         }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

UI_ERR SetColumnDiam ( INT32  Diam, pCOLUMN_STATUS status )

/**end_proto**/
{
   UI_ERR error;

      if ( (error = ValidateDiam( Diam )) == OK )
      {
           LockResource( &Inst_Status.Pneu.Resource_Lock );

           ChangeColumnDiam( Diam, status );

           ReleaseResource ( &Inst_Status.Pneu.Resource_Lock );
      }

      return error;
}


/**begin_proto**/

UI_ERR DcSetColumnDiam ( INT32  Diam, pCOLUMN_STATUS status )

/**end_proto**/
{
   UI_ERR error;

      if ( (error = ValidateDiam( Diam )) == OK )
      {
           ChangeColumnDiam( Diam, status );
      }

      return error;
}


/**begin_proto**/

void ChangeColumnDiam ( INT32  diam, pCOLUMN_STATUS status )

/**end_proto**/
{

     if ( diam != status->Config->Diam )
     {
           status->Config->Diam = diam;
           status->Config->Film_Thickness = 0;

           /* performs a reconfigure */
           UpdateColumnCalibMode( status, UNCALIBRATED );
           StrNCpy( (BIT8 *)status->Config->ID_String, (BIT8 *)" ", 1 );
     }

     switch ( status->Config->Source )
     {
         case FRNT_INLET: SlamInletSetpt( &Inst_Status.Pneu.Frnt_Inlet );
                          break;
         case BACK_INLET: SlamInletSetpt( &Inst_Status.Pneu.Back_Inlet );
                          break;
         default:         ; /* default case only to keep lint happy */
     }

     SourceSetptChanged( status->Config->Source );

     LogSetptChange( status->Position == 1 ? COL1_DIAM : COL2_DIAM, diam, 0 );
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

UI_ERR SetColumnLength (  INT32  length, pCOLUMN_STATUS status )

/**end_proto**/
{
      UI_ERR error;

      if ( (error = ValidateLength( length )) == OK )
      {
           LockResource( &Inst_Status.Pneu.Resource_Lock );

           ChangeColumnLength( length, status );

           ReleaseResource ( &Inst_Status.Pneu.Resource_Lock );

           FixSmplgEndViolations( status );
      }

      return error;
}


/**begin_proto**/

UI_ERR DcSetColumnLength (  INT32  length, pCOLUMN_STATUS status )

/**end_proto**/
{
      UI_ERR error;

      if ( (error = ValidateLength( length )) == OK )
      {
           ChangeColumnLength( length, status );
      }

      return error;
}

/**begin_proto**/

void ChangeColumnLength (  INT32  length, pCOLUMN_STATUS status )

/**end_proto**/
{

     if ( length != status->Config->Length )
     {
           status->Config->Length = length;

           /* performs a reconfigure */
           UpdateColumnCalibMode( status, UNCALIBRATED );
           StrNCpy( (BIT8 *)status->Config->ID_String, (BIT8 *)" ", 1 );
     }

     switch ( status->Config->Source )
     {
         case FRNT_INLET: SlamInletSetpt( &Inst_Status.Pneu.Frnt_Inlet );
                          break;
         case BACK_INLET: SlamInletSetpt( &Inst_Status.Pneu.Back_Inlet );
                          break;
         default:         ; /* default case only to keep lint happy */
     }

     LogSetptChange( status->Position == 1 ? COL1_LENGTH : COL2_LENGTH, length, 0 );

     SourceSetptChanged( status->Config->Source );

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

UI_ERR SetColumnFilmThickness (  INT32  thickness, pCOLUMN_STATUS status )

/**end_proto**/
{
      UI_ERR error;

      if ( (error = ValidateFilmThickness( thickness, status )) == OK )
      {
           LockResource( &Inst_Status.Pneu.Resource_Lock );

           ChangeColumnFilmThickness( thickness, status );

           ReleaseResource ( &Inst_Status.Pneu.Resource_Lock );
      }

      return error;
}


/**begin_proto**/

UI_ERR DcSetColumnFilmThickness (  INT32  thickness, pCOLUMN_STATUS status )

/**end_proto**/
{
      UI_ERR error;

      if ( (error = ValidateFilmThickness( thickness, status )) == OK )
      {
           ChangeColumnFilmThickness( thickness, status );
      }

      return error;
}

/**begin_proto**/

void ChangeColumnFilmThickness (  INT32  thickness, pCOLUMN_STATUS status )

/**end_proto**/
{
     status->Config->Film_Thickness = thickness;  /* microns * Scaling */

     if ( !DoingMethodInstall() ) ReconfigurePneu();

     LogSetptChange( status->Position == 1 ? COL1_FILM_THICK : COL2_FILM_THICK, thickness, 0 );

     SourceSetptChanged( status->Config->Source );

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

BIT8 ColumnDefined ( pCOLUMN_STATUS status )

/**end_proto**/
{

    return status->Config->Defined;

}


/**begin_proto**/

SOURCE_CONNECTION GetColumnSource ( pCOLUMN_STATUS status )

/**end_proto**/
{

    return status->Config->Source;

}

/**begin_proto**/

UI_ERR ValidateColumnSource ( SOURCE_CONNECTION source )

/**end_proto**/
{

     if (( source == FRNT_INLET ) && ( Inst_Config.Pneu.Frnt_Inlet.Type != NO_INLET )) return OK;
     if (( source == BACK_INLET ) && ( Inst_Config.Pneu.Back_Inlet.Type != NO_INLET )) return OK;
     if (( source == AUX_3      ) && ( Inst_Config.Pneu.Aux_3.Functional    ))         return OK;
     if (( source == AUX_4      ) && ( Inst_Config.Pneu.Aux_4.Functional    ))         return OK;
     if (( source == AUX_5      ) && ( Inst_Config.Pneu.Aux_5.Functional    ))         return OK;
     if  ( source == UNKNOWN_SOURCE )                                                  return OK;
     return INVALID_PARAM;

}

/**begin_proto**/

UI_ERR SetColumnSource( SOURCE_CONNECTION source, pCOLUMN_STATUS status )

/**end_proto**/
{

      UI_ERR  error;

      if ( (error = ValidateColumnSource ( source )) == OK )
      {
           LockResource( &Inst_Status.Pneu.Resource_Lock );

           error = ChangeColumnSource( source, status, GetOvenInitTemp() );

           ReleaseResource ( &Inst_Status.Pneu.Resource_Lock );
      }

      return error;
}


/**begin_proto**/

UI_ERR DcSetColumnSource( SOURCE_CONNECTION source, pCOLUMN_STATUS status )

/**end_proto**/
{

      UI_ERR  error;

      if ( (error = ValidateColumnSource ( source )) == OK )
      {
           error = ChangeColumnSource( source, status, GetOvenInitTemp() );
      }

      return error;
}

/**begin_proto**/

UI_ERR ChangeColumnSource( SOURCE_CONNECTION source, pCOLUMN_STATUS status, U_INT16 oven_temp )

/**end_proto**/
{

      U_INT16 pres_iu;
      U_INT16 p_scale;
      SOURCE_CONNECTION old_source;
      U_INT16 aux_num;
      UI_ERR  error;

      error   = OK;
      aux_num = 0;

      old_source = GetColumnSource( status );

      status->Config->Source = source;

      switch ( old_source )
      {
          case FRNT_INLET: ChangeInletMiserMode ( OFF, &Inst_Status.Pneu.Frnt_Inlet );
                           SlamInletSetpt( &Inst_Status.Pneu.Frnt_Inlet );
                           break;

          case BACK_INLET: ChangeInletMiserMode ( OFF, &Inst_Status.Pneu.Back_Inlet );
                           SlamInletSetpt( &Inst_Status.Pneu.Back_Inlet );
                           break;

          case AUX_3:      ResetAuxPres( &Inst_Status.Pneu.Aux.Aux_3 );
                           break;

          case AUX_4:      ResetAuxPres( &Inst_Status.Pneu.Aux.Aux_4 );
                           break;

          case AUX_5:      ResetAuxPres( &Inst_Status.Pneu.Aux.Aux_5 );
                           break;

                       /* default case only to keep lint happy */
          default:         ;
      }


      if ( SourcePressureControlled( status )  )
      {
           switch ( source )
           {
              case FRNT_INLET: pres_iu = Active_Wkfile.Pneu.Frnt_Inlet.Inlet_Pressure;
                               p_scale = Inst_Status.Pneu.Frnt_Inlet.Dcm2_Per_IU;
                               Inst_Status.Pneu.Frnt_Inlet.Controlled_By_Column =
                                                      SourceControlledByColumn ( FRNT_INLET );
                               break;
              case BACK_INLET: pres_iu = Active_Wkfile.Pneu.Back_Inlet.Inlet_Pressure;
                               p_scale = Inst_Status.Pneu.Back_Inlet.Dcm2_Per_IU;
                               Inst_Status.Pneu.Back_Inlet.Controlled_By_Column =
                                                      SourceControlledByColumn ( BACK_INLET );
                               break;
              case AUX_3:
                               if ( Inst_Config.Pneu.Aux_3.Gas_Type == Air )
                               {
                                   Inst_Config.Pneu.Aux_3.Gas_Type = N2;
                                   SendAuxGasChangeRequest( &Inst_Status.Pneu.Aux.Aux_3, N2 );
                                   error = NOT_COMPATIBLE;
                               }
                               pres_iu = Active_Wkfile.Pneu.Aux_3.Desired_Pressure;
                               p_scale = Inst_Status.Pneu.Aux.Aux_3.Dcm2_Per_IU;
                               Inst_Status.Pneu.Aux.Aux_3.Controlled_By_Column =
                                                      SourceControlledByColumn ( AUX_3 );
                               DisableRamp( (pRAMPINFO)(&Inst_Status.Pneu.Aux.Aux_3.Ramp_Info) );
                               aux_num = 3;
                               break;
              case AUX_4:
                               if ( Inst_Config.Pneu.Aux_4.Gas_Type == Air )
                               {
                                   Inst_Config.Pneu.Aux_4.Gas_Type = N2;
                                   SendAuxGasChangeRequest( &Inst_Status.Pneu.Aux.Aux_4, N2 );
                                   error = NOT_COMPATIBLE;
                               }
                               pres_iu = Active_Wkfile.Pneu.Aux_4.Desired_Pressure;
                               p_scale = Inst_Status.Pneu.Aux.Aux_4.Dcm2_Per_IU;
                               Inst_Status.Pneu.Aux.Aux_4.Controlled_By_Column =
                                                      SourceControlledByColumn ( AUX_4 );
                               DisableRamp( (pRAMPINFO)(&Inst_Status.Pneu.Aux.Aux_4.Ramp_Info) );
                               aux_num = 4;
                               break;
              case AUX_5:
                               if ( Inst_Config.Pneu.Aux_5.Gas_Type == Air )
                               {
                                   Inst_Config.Pneu.Aux_5.Gas_Type = N2;
                                   SendAuxGasChangeRequest( &Inst_Status.Pneu.Aux.Aux_5, N2 );
                                   error = NOT_COMPATIBLE;
                               }
                               pres_iu = Active_Wkfile.Pneu.Aux_5.Desired_Pressure;
                               p_scale = Inst_Status.Pneu.Aux.Aux_5.Dcm2_Per_IU;
                               Inst_Status.Pneu.Aux.Aux_5.Controlled_By_Column =
                                                      SourceControlledByColumn ( AUX_5 );
                               DisableRamp( (pRAMPINFO)(&Inst_Status.Pneu.Aux.Aux_5.Ramp_Info) );
                               aux_num = 5;
                               break;
                       /* default case only to keep lint happy */
              default:         pres_iu = 0;
                               aux_num = 0;
                               p_scale = 1;
           }

           UpdateColumnsDamnIt(pres_iu, oven_temp, source, p_scale );

           if ( !DoingMethodInstall() ) ReconfigurePneu();

      }
      else
      {
           if (( status->Wkfile->Control_Mode == RAMP_PRES )   ||
               ( status->Wkfile->Control_Mode == CONST_PRES ))
           {
                /* now an unsupported mode */
               (void)SetColumnControlMode( CONST_FLOW, status );
           }
           switch ( source )
           {
              case FRNT_INLET: ModifyInletFlowSetpt( &Inst_Status.Pneu.Frnt_Inlet );
                               break;
              case BACK_INLET: ModifyInletFlowSetpt( &Inst_Status.Pneu.Back_Inlet );
                               break;
           }

           SlamSourceSetpt( status );

           if ( !DoingMethodInstall() ) ReconfigurePneu();
      }


      LogSetptChange( status->Position == 1 ? COL1_SOURCE : COL2_SOURCE, aux_num, (INT32)source );

      FixSmplgEndViolations( status ) ;

      return error;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/


/**begin_proto**/

OUTLET_CONNECTION GetColumnOutlet ( pCOLUMN_STATUS status )

/**end_proto**/
{

    return status->Config->Outlet;

}

/**begin_proto**/

UI_ERR ValidateColumnOutlet ( OUTLET_CONNECTION outlet )

/**end_proto**/
{

     if ( outlet == FRNT_DET )  return OK;
     if ( outlet == BACK_DET )  return OK;
     if ( outlet == MSD )       return OK;
     if ( outlet == AED )       return OK;
     if ( outlet == UNKNOWN_OUTLET )  return OK;
     return INVALID_PARAM;

}

/**begin_proto**/

UI_ERR SetColumnOutlet( OUTLET_CONNECTION outlet, pCOLUMN_STATUS status )

/**end_proto**/
{

      UI_ERR error;

      if ( (error = ValidateColumnOutlet ( outlet )) == OK )
      {
           LockResource( &Inst_Status.Pneu.Resource_Lock );

           ChangeColumnOutlet( outlet, status );

           ReleaseResource ( &Inst_Status.Pneu.Resource_Lock );
      }

      return error;
}


/**begin_proto**/

UI_ERR DcSetColumnOutlet( OUTLET_CONNECTION outlet, pCOLUMN_STATUS status )

/**end_proto**/
{

      UI_ERR error;

      if ( (error = ValidateColumnOutlet ( outlet )) == OK )
      {
           ChangeColumnOutlet( outlet, status );
      }

      return error;
}

/**begin_proto**/

void ChangeColumnOutlet( OUTLET_CONNECTION outlet, pCOLUMN_STATUS status )

/**end_proto**/
{

    status->Config->Outlet = outlet;

    if ( !DoingMethodInstall() ) ReconfigurePneu();

    LogSetptChange( status->Position == 1 ? COL1_OUTLET : COL2_OUTLET, 0, (INT32)outlet );

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

ON_OFF GetColumnVacuumComp ( pCOLUMN_STATUS status )

/**end_proto**/
{

      return status->Config->Vacuum_Comp;

}

/**begin_proto**/

UI_ERR ValidateColumnVacuumComp ( ON_OFF state )

/**end_proto**/
{
      if ( state == ON ) return OK;
      if ( state == OFF) return OK;
      return INVALID_PARAM;

}

/**begin_proto**/

UI_ERR SetColumnVacuumComp ( ON_OFF state, pCOLUMN_STATUS status )

/**end_proto**/

{
     UI_ERR error;

     if ( (error = ValidateColumnVacuumComp( state )) == OK )
     {
         status->Config->Vacuum_Comp = state;
         if ( state == ON ) status->Config->Outlet_Pressure_Correction = OFF;
         SourceSetptChanged( status->Config->Source );

         if ( !DoingMethodInstall() )  RangeCheckColumnRamps( status );
     }

     if ( state == ON )
     {
          LogSetptChange( status->Position == 1 ? COL1_VACUUM_COMP_ON : COL2_VACUUM_COMP_ON, 0, 0 );
     }
     else
     {
          LogSetptChange( status->Position == 1 ? COL1_VACUUM_COMP_OFF : COL2_VACUUM_COMP_OFF, 0, 0 );
     }

     return error;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

TRUE_FALSE ColumnOutletPresCompEnabled ( pCOLUMN_STATUS status )

/**end_proto**/
{

      return (TRUE_FALSE)status->Config->Outlet_Pressure_Correction;

}

/**begin_proto**/

INT32 GetColumnOutletPresCompSetpt ( pCOLUMN_STATUS status )

/**end_proto**/
{

      return  ConvertPresIuToDisplay ( status->Config->Outlet_Correction, 80 );

}

/**begin_proto**/

INT32 DcGetColumnOutletPresCompSetpt ( pCOLUMN_STATUS status )

/**end_proto**/
{

      return  ConvertPresIuToDcu ( status->Config->Outlet_Correction, 80 );

}

/**begin_proto**/

UI_ERR ValidateColumnOutletPresComp ( INT32 pres )

/**end_proto**/
{

   switch( Inst_Config.Pneu.Pressure_Display_Units )
   {
       case DISPLAY_PSI: if ( pres < MIN_OUTLET_PRES_PSI ) return PARAM_TOO_SMALL;
                         if ( pres > MAX_OUTLET_PRES_PSI ) return PARAM_TOO_LARGE;
                         return OK;
       case DISPLAY_BAR: if ( pres < MIN_OUTLET_PRES_BAR ) return PARAM_TOO_SMALL;
                         if ( pres > MAX_OUTLET_PRES_BAR ) return PARAM_TOO_LARGE;
                         return OK;
       case DISPLAY_KPA: if ( pres < MIN_OUTLET_PRES_KPA ) return PARAM_TOO_SMALL;
                         if ( pres > MAX_OUTLET_PRES_KPA ) return PARAM_TOO_LARGE;
                         return OK;
       default: return INVALID_PARAM;

   }

}

/**begin_proto**/

INT32 GetMaxColPresComp( pCOLUMN_STATUS status )

/**end_proto**/
{
   (void)status;

   switch( Inst_Config.Pneu.Pressure_Display_Units )
   {
       case DISPLAY_PSI: return MAX_OUTLET_PRES_PSI;
       case DISPLAY_BAR: return MAX_OUTLET_PRES_BAR;
       case DISPLAY_KPA: return MAX_OUTLET_PRES_KPA;
       default:          return 0;
   }
}


/**begin_proto**/

UI_ERR SetColumnOutletPresComp ( ON_OFF state, pCOLUMN_STATUS status )

/**end_proto**/

{

     if (( state != ON ) && ( state != OFF)) return INVALID_PARAM;

     if ( state == ON ) status->Config->Vacuum_Comp = OFF;

     status->Config->Outlet_Pressure_Correction = state;

     if ( ! DoingMethodInstall() )  RangeCheckColumnRamps( status );

     SourceSetptChanged( status->Config->Source );

     if ( state == ON )
     {
          LogSetptChange( status->Position == 1 ? COL1_PRES_CORRECT_ON : COL2_PRES_CORRECT_ON, 0, 0 );
     }
     else
     {
          LogSetptChange( status->Position == 1 ? COL1_PRES_CORRECT_OFF : COL2_PRES_CORRECT_OFF, 0, 0 );
     }

     return OK;

}

/**begin_proto**/

UI_ERR SetColumnOutletPresCompSetpt ( INT32 pres, pCOLUMN_STATUS status )

/**end_proto**/

{
     U_INT16 pres_iu;
     UI_ERR  error;

     pres_iu = ConvertPresDisplayToIu( pres, 80 );

     if ( (error = ValidateColumnOutletPresComp( pres )) == OK )
     {
           LockResource( &Inst_Status.Pneu.Resource_Lock );

           status->Config->Vacuum_Comp = OFF;
           status->Config->Outlet_Pressure_Correction = ON;

           ChangeColumnOutletPresSetpt (  pres_iu,  pres,  status );

           ReleaseResource ( &Inst_Status.Pneu.Resource_Lock );
     }

     return error;
}
/**begin_proto**/

UI_ERR DcSetColumnOutletPresCompSetpt ( INT32 pres, pCOLUMN_STATUS status )

/**end_proto**/

{
     U_INT16 pres_iu;
     INT32   pres_du;
     UI_ERR  error;

     pres_iu = ConvertPresDcuToIu( pres, 80 );
     pres_du = ConvertPresIuToDisplay( pres_iu, 80 );

     if ( (error = ValidateColumnOutletPresComp( pres_du )) == OK )
     {
         ChangeColumnOutletPresSetpt (  pres_iu,  pres_du,  status );
     }

     return error;
}

/**begin_proto**/

void ChangeColumnOutletPresSetpt ( U_INT16 pres_iu, INT32 pres, pCOLUMN_STATUS status )

/**end_proto**/

{
     status->Config->Outlet_Correction = pres_iu;

     if ( ! DoingMethodInstall() )  RangeCheckColumnRamps( status );

     SourceSetptChanged( status->Config->Source );

     LogSetptChange( status->Position == 1 ? COL1_CORRECT_PRES : COL2_CORRECT_PRES, pres, (INT32)GetPresUnits() );

}
/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

INT32 GetColumnHeadPres ( pCOLUMN_STATUS status )

/**end_proto**/
{
      return ConvertPresIuToDisplay ( GetColumnHeadPresIu ( status ), status->Dcm2_Per_IU );
}



/**begin_proto**/

INT32 DcGetColumnHeadPres ( pCOLUMN_STATUS status )

/**end_proto**/
{
      return ConvertPresIuToDcu ( GetColumnHeadPresIu ( status ), status->Dcm2_Per_IU );
}

/**begin_proto**/

U_INT16 GetColumnHeadPresIu ( pCOLUMN_STATUS status )

/**end_proto**/
{
      U_INT16 pres_iu;
      U_INT16 oven_temp;
      BIT8    epc_source;

      epc_source = EpcSource( status );

      if ( epc_source && ( GetColumnSourceState ( status ) != ON ))
      {
          return 0;
      }

      oven_temp = GetCurrentOvenTemp();

      if ( SourcePressureControlled( status ) )
      {
          /* this represents a setpoint */

          if ( epc_source )
          {
              pres_iu = GetColumnPresSetptIu(status, oven_temp);
          }
          else
          {
              /* flow calculator mode */
              pres_iu = status->Active_Pressure;
          }
      }
      else
      {
          /* this represents an actual */

          pres_iu = status->Current_Head_Pressure;
      }

      return pres_iu;
}


/**begin_proto**/

UI_ERR ValidateColumnHeadPres ( INT32 pressure, pCOLUMN_STATUS status )

/**end_proto**/
{

    INT32 range;

    if ( status->Config->Source == UNKNOWN_SOURCE ) return INVALID_PARAM;

    switch ( status->Config->Source )
    {
       case FRNT_INLET: range = GetInletMaxPres( &Inst_Status.Pneu.Frnt_Inlet );
                        break;
       case BACK_INLET: range = GetInletMaxPres( &Inst_Status.Pneu.Back_Inlet );
                        break;
       case AUX_3:      range = GetAuxMaxPres( &Inst_Status.Pneu.Aux.Aux_3 );
                        break;
       case AUX_4:      range = GetAuxMaxPres( &Inst_Status.Pneu.Aux.Aux_4 );
                        break;
       case AUX_5:      range = GetAuxMaxPres( &Inst_Status.Pneu.Aux.Aux_5 );
                        break;
       default:         range = 0;
    }


   if (( pressure >= 0 ) && ( pressure <= range )) return OK;
   return INVALID_PARAM;

}

/**begin_proto**/

UI_ERR  SetColumnHeadPres (INT32 pressure, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT16 pres_iu;
     UI_ERR  error;

     pres_iu =  ConvertPresDisplayToIu ( pressure, status->Dcm2_Per_IU );


     if ( (error = ValidateColumnHeadPres( pressure, status )) == OK )
     {
         ChangeColumnHeadPres( pres_iu, pressure, status, GetCurrentOvenTemp() );
         ChangeColumnSourceState( status, ON );
     }

     return error;
}


/**begin_proto**/

UI_ERR  DcSetColumnHeadPres (INT32 pressure, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT16 pres_iu;
     INT16   pres;
     UI_ERR  error;

     pres_iu =  ConvertPresDcuToIu     ( pressure, status->Dcm2_Per_IU );
     pres    =  ConvertPresIuToDisplay ( pres_iu,  status->Dcm2_Per_IU );


     if ( (error = ValidateColumnHeadPres( pres, status )) == OK )
     {
         ChangeColumnHeadPres( pres_iu, pres, status, GetCurrentOvenTemp() );
     }

     return error;
}


/**begin_proto**/

void ChangeColumnHeadPres (U_INT16 pres_iu, INT32 pressure, pCOLUMN_STATUS status, U_INT16 oven_temp )

/**end_proto**/
{

     UpdateColumnHeadPres( pres_iu, status, oven_temp );

     LogSetptChange( status->Position == 1 ? COL1_PRESSURE : COL2_PRESSURE, pressure, (INT32)GetPresUnits() );

}


/**begin_proto**/

void UpdateColumnHeadPres (U_INT16 pres_iu, pCOLUMN_STATUS status, U_INT16 oven_temp )

/**end_proto**/
{

     status->Active_Pressure = pres_iu;      /* this line allows the flow calc to work */

     UpdateColumns ( pres_iu, oven_temp, status->Config->Source, status->Dcm2_Per_IU );


}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

INT32 DcGetColumnActualFlow( pCOLUMN_STATUS status )

/**end_proto**/
{

     if (( status->Config->Defined ) && ( EpcSource( status ) ))
     {
           return DcGetColumnVFlowActual ( status );
     }
     else if (( !status->Config->Defined ) &&
              (( GetColSourceType ( status ) == PP_INLET ) || ( GetColSourceType ( status ) == SIMDIST_INLET ) )&&
              ( EpcSource( status ) )
             )
     {
           return DcGetColumnVFlowActual ( status );
     }
     else
     {
           return -1;
     }

}

/**begin_proto**/

INT32 GetColumnVFlowActual ( pCOLUMN_STATUS status )

/**end_proto**/
{

      return ConvertFlowIuToDisplay( status->NTP_Adjusted_Current_Flow, status->IU_Scaling );

}
/**begin_proto**/

INT32 DcGetColumnVFlowActual ( pCOLUMN_STATUS status )

/**end_proto**/
{

      return ConvertFlowIuToDcu( status->NTP_Adjusted_Current_Flow, status->IU_Scaling );

}
/**begin_proto**/

INT32 GetColumnVFlow ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return ConvertFlowIuToDisplay( GetColumnVFlowIu ( status ), status->IU_Scaling );
}

/**begin_proto**/

INT32 DcGetColumnVFlow ( pCOLUMN_STATUS status )

/**end_proto**/
{

    return ConvertFlowIuToDcu( GetColumnVFlowIu ( status ), status->IU_Scaling );

}

/**begin_proto**/

U_INT32 GetColumnVFlowIu ( pCOLUMN_STATUS status )

/**end_proto**/
{
      U_INT16 oven_temp;
      U_INT16 Po;
      U_INT32 flow;

      if ( EpcSource( status ))
      {
           if ( SourcePressureControlled ( status ) )
           {
                if (( GetColumnSourceState ( status ) != ON ) || ( status->Active_Pressure == 0 ))
                {
                     flow = 0;
                }
                else
                {
                     flow = status->NTP_Flow_Setpt;
                }
           }
           else
           {

                if ( VIFlowSourceChk(status))
                {
                     flow = status->NTP_Adjusted_Current_Flow;
                }
                else
                {
                     if ( GetColumnSourceState ( status ) != ON )
                     {
                          flow = 0;
                     }
                     else
                     {
                          /* flow controlled purged packed */
                          flow = status->Active_Flow;
                     }
                }
           }
      }
      else  /* NOT EpcSource */
      {
          oven_temp = GetCurrentOvenTemp();

          if ( SourcePressureControlled ( status ) )
          {
              Po = GetNtpOutletPressure( status );

              flow = CalcVFlow(status, oven_temp, status->Active_Pressure, Po );
          }
          else
          {
              flow = 0;
          }
      }

      return flow;
}

/**begin_proto**/

UI_ERR ValidateColumnVFlow ( INT32 flow, pCOLUMN_STATUS status )

/**end_proto**/
{
      if ( flow > GetSourceMaxFlow ( status, GetCurrentOvenTemp() ) ) return PARAM_TOO_LARGE;
      if ( flow < 0 )                                                 return PARAM_TOO_SMALL;

      return OK;
}

/**begin_proto**/

UI_ERR DcValidateColumnVFlow ( INT32 flow, pCOLUMN_STATUS status )

/**end_proto**/
{
      if ( flow > GetSourceMaxFlow ( status, GetOvenInitTemp() ) )    return PARAM_TOO_LARGE;
      if ( flow < 0 )                                                 return PARAM_TOO_SMALL;

      return OK;
}

/**begin_proto**/

UI_ERR SetColumnVFlow ( INT32 flow, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT32 flow_iu;
     UI_ERR  error;

     flow_iu = ConvertFlowDisplayToIu( flow, status->IU_Scaling );

     if ( (error = ValidateColumnVFlow( flow, status )) == OK )
     {
         ChangeColumnVFlow( flow_iu, flow, status, GetCurrentOvenTemp() );
         ChangeColumnSourceState( status, ON );
     }

     return error;

}


/**begin_proto**/

UI_ERR DcSetColumnVFlow ( INT32 flow, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT32 flow_iu;
     INT32   flow_du;
     UI_ERR  error;

     flow_iu = ConvertFlowDcuToIu    ( flow,    status->IU_Scaling );
     flow_du = ConvertFlowIuToDisplay( flow_iu, status->IU_Scaling );

     if ( (error = ValidateColumnVFlow( flow_du, status )) == OK )
     {
         ChangeColumnVFlow( flow_iu, flow_du, status, GetCurrentOvenTemp() );
     }

     return error;

}



/**begin_proto**/

void ChangeColumnVFlow ( U_INT32 flow_iu, INT32 flow, pCOLUMN_STATUS status, U_INT16 oven_temp )

/**end_proto**/
{

     UpdateColumnVFlow( flow_iu, status, oven_temp );

     LogSetptChange( status->Position == 1 ? COL1_FLOW : COL2_FLOW, flow, 0 );

}



/**begin_proto**/

void UpdateColumnVFlow ( U_INT32 flow_iu, pCOLUMN_STATUS status, U_INT16 oven_temp )

/**end_proto**/
{

     U_INT16 pres_iu;
     U_INT16 Po;

     Po = GetNtpOutletPressure( status );

     if ( SourcePressureControlled( status ) )
     {
         pres_iu = CalcPiFromVFlow( flow_iu, oven_temp, Po, status );
         status->Active_Pressure = pres_iu;

         UpdateColumns ( pres_iu, oven_temp, status->Config->Source, status->Dcm2_Per_IU );

     }
     else
     {
         /* flow controlled packed inlet */
         if ( RunActiveOrPostTime() == FALSE )
         {
              if ( GetRampType((pRAMPINFO)(status->Ramp_Info)) == FLOW_RAMP )
              {
                  SetRampInitValue( (pRAMPINFO)(status->Ramp_Info),
                                           QuadWordMultiplyDivide( flow_iu,
                                                                   status->Ramp_Setpt.Ramp_Flow_Scaling,
                                                                   status->IU_Scaling ));
              }
         }


         status->Ramp_Setpt.Column_V_Flow = QuadWordMultiplyDivide( flow_iu,
                                                                    status->Ramp_Setpt.Ramp_Flow_Scaling,
                                                                    status->IU_Scaling );
         status->Desired_Column_Flow    = flow_iu;

         SlamColumnSetpt( status->Ramp_Setpt.Column_V_Flow, status );

         switch ( status->Config->Source )
         {
            case FRNT_INLET: ModifyInletFlowSetpt( &Inst_Status.Pneu.Frnt_Inlet );
                             break;
            case BACK_INLET: ModifyInletFlowSetpt( &Inst_Status.Pneu.Back_Inlet );
                             break;
         }
     }



}



/**begin_proto**/

INT32 GetColumnAvgVelocity ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return ConvertVelIuToDisplay( GetColumnAvgVelocityIu ( status ), status->Vel_IU_Scaling );
}


/**begin_proto**/

INT32 DcGetColumnAvgVelocity ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return ConvertVelIuToDcu( GetColumnAvgVelocityIu ( status ), status->Vel_IU_Scaling );
}

/**begin_proto**/

U_INT32 GetColumnAvgVelocityIu ( pCOLUMN_STATUS status )

/**end_proto**/
{
    U_INT32 u_avg;

      if ( EpcSource( status ))
      {
          if (( GetColumnSourceState ( status ) != ON ) ||
              ( status->Active_Pressure == 0 ))
          {
              u_avg = 0;
          }
          else
          {
              u_avg = status->NTP_Uavg_Setpt;
          }
      }
      else
      {
          if ( SourcePressureControlled ( status ) )
          {
              u_avg = CalcUavg(status, GetCurrentOvenTemp(), status->Active_Pressure, GetNtpOutletPressure( status ));
          }
          else
          {
              u_avg = 0;
          }
      }

      return u_avg;

}

/**begin_proto**/

UI_ERR ValidateColumnAvgVel ( U_INT32 vel_iu, pCOLUMN_STATUS status )

/**end_proto**/
{

      U_INT16 pres_iu;
      U_INT16 oven_temp;
      U_INT16 Po;

      Po = GetNtpOutletPressure( status );

      oven_temp = GetCurrentOvenTemp();

      pres_iu = CalcPiFromUavg ( vel_iu, oven_temp, Po, status );

      if ( pres_iu == 0 ) return PARAM_TOO_SMALL; /* zero pres means a velocity less than obtainable w VC */

      return ValidateColumnHeadPres( ConvertPresIuToDisplay(pres_iu, status->Dcm2_Per_IU), status );


}

/**begin_proto**/

UI_ERR SetColumnAvgVel ( INT32 vel, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT32 vel_iu;
     UI_ERR  error;

     if ( vel < 0 ) return PARAM_TOO_SMALL;

     vel_iu = ConvertVelDisplayToIu( vel, status->Vel_IU_Scaling );

     if ( (error = ValidateColumnAvgVel( vel_iu, status )) == OK )
     {
          ChangeColumnAvgVel( vel_iu, vel, status );
          ChangeColumnSourceState( status, ON );
     }

     return error;
}

/**begin_proto**/

UI_ERR DcSetColumnAvgVel ( INT32 vel, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT32 vel_iu;
     INT32   vel_du;
     UI_ERR  error;

     if ( vel < 0 ) return PARAM_TOO_SMALL;

     vel_iu = ConvertVelDcuToIu    ( vel,    status->Vel_IU_Scaling );
     vel_du = ConvertVelIuToDisplay( vel_iu, status->Vel_IU_Scaling );

     if ( (error = ValidateColumnAvgVel( vel_iu, status )) == OK )
     {
         ChangeColumnAvgVel( vel_iu, vel_du, status );
     }

     return error;
}

/**begin_proto**/

void ChangeColumnAvgVel ( U_INT32 vel_iu, INT32 vel, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT16 pres_iu;
     U_INT16 Po;
     U_INT16 oven_temp;

     Po = GetNtpOutletPressure ( status );

     oven_temp = GetCurrentOvenTemp();

     pres_iu = CalcPiFromUavg( vel_iu, oven_temp, Po, status );

     status->Active_Pressure = pres_iu;

     UpdateColumns ( pres_iu, oven_temp, status->Config->Source, status->Dcm2_Per_IU );

     LogSetptChange( status->Position == 1 ? COL1_VELOCITY : COL2_VELOCITY, vel, 0 );

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

CONTROL_MODE GetColumnControlMode( pCOLUMN_STATUS status )

/**end_proto**/
{
         return status->Wkfile->Control_Mode;

}

/**begin_proto**/

UI_ERR ValidateColumnControlMode ( CONTROL_MODE mode, pCOLUMN_STATUS status )

/**end_proto**/
{

    COL_SOURCE_TYPE source;
    BIT8        defined;

     switch ( mode )
     {
         case CONST_PRES:
         case RAMP_PRES:
         case CONST_FLOW:
         case RAMP_FLOW:    break;

         default:           return INVALID_PARAM;
     }

    source  = GetColSrcType     ( status );

    if ( Inst_Config.Pneu.Column_1.Source == Inst_Config.Pneu.Column_2.Source )
    {
       defined = ( ColumnDefined ( status ) && ColumnDefined( &Inst_Status.Pneu.Column_2 ));
    }
    else
    {
       defined = ColumnDefined ( status );
    }

    return ( NativeRampType [ defined ][ (U_INT8)source ][ (U_INT8)mode ] == INVALID_RAMP ) ? INVALID_PARAM : OK;

}

/**begin_proto**/

UI_ERR DcSetColumnControlMode ( CONTROL_MODE mode, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT16 pres_iu;
     U_INT16 oven_temp;
     UI_ERR  error;


     if ( (error = ValidateColumnControlMode ( mode, status )) == OK )
     {
           status->Wkfile->Control_Mode = mode;

           ChangeRampType( status );

           /* now, convert the current setpts to reflect the current mode */

           oven_temp = GetCurrentOvenTemp();
           pres_iu = GetColumnPresSetptIu( status, oven_temp );

           UpdateColumnsDamnIt(pres_iu, oven_temp, status->Config->Source, status->Dcm2_Per_IU );

           LogSetptChange( status->Position == 1 ? COL1_CONTROL_MODE : COL2_CONTROL_MODE, 0, (INT32)mode );

     }

     return error;

}

/**begin_proto**/

UI_ERR SetColumnControlMode ( CONTROL_MODE mode, pCOLUMN_STATUS status )

/**end_proto**/
{
     UI_ERR  err;
           err = DcSetColumnControlMode ( mode, status );
           VISamplingEndChk( status );
           return err ;
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

COL_SOURCE_TYPE GetColSourceType ( pCOLUMN_STATUS status )

/**end_proto**/
{

    switch ( status->Config->Source )
    {
       case FRNT_INLET: switch ( Inst_Config.Pneu.Frnt_Inlet.Type )
                        {
                         case  PP:              return PP_INLET;
                         case  COC:             return COC_INLET;
                         case  SS:              return SS_INLET;
                         case  PTV:             return PTV_INLET;
                         case  ACI:             return ACI_INLET;
                         case  SIMDIST:         return SIMDIST_INLET;
                         case  CIS3 :           return CIS3_INLET;
                         case  CIS4:            return CIS4_INLET;
                         case  VOLATILES:       return VOLATILES_INLET;
                         case  MANUAL_PP:       return MAN_PP_INLET;
                         case  MANUAL_COC:      return MAN_COC_INLET;
                         case  MANUAL_ACI:      return MAN_ACI_INLET;
                         case  MANUAL_SS:       return MAN_SS_INLET;
                         case  UNKNOWN_INLET:
                         case  NO_INLET:        return UNKNOWN_TYPE;
                         default:               return UNKNOWN_TYPE;
                        }

       case BACK_INLET: switch ( Inst_Config.Pneu.Back_Inlet.Type )
                        {
                         case  PP:              return PP_INLET;
                         case  COC:             return COC_INLET;
                         case  SS:              return SS_INLET;
                         case  PTV:             return PTV_INLET;
                         case  ACI:             return ACI_INLET;
                         case  SIMDIST:         return SIMDIST_INLET;
                         case  CIS3 :           return CIS3_INLET;
                         case  CIS4:            return CIS4_INLET;
                         case  VOLATILES:       return VOLATILES_INLET;
                         case  MANUAL_PP:       return MAN_PP_INLET;
                         case  MANUAL_COC:      return MAN_COC_INLET;
                         case  MANUAL_ACI:      return MAN_ACI_INLET;
                         case  MANUAL_SS:       return MAN_SS_INLET;
                         case  UNKNOWN_INLET:
                         case  NO_INLET:        return UNKNOWN_TYPE;
                         default:               return UNKNOWN_TYPE;
                        }

       case AUX_3:
       case AUX_4:
       case AUX_5:   return SOME_AUX;


       case UNKNOWN_SOURCE:  return UNKNOWN_TYPE;
       default:              return UNKNOWN_TYPE;
    }

}

/**begin_proto**/

BIT8 EpcSource ( pCOLUMN_STATUS status )

/**end_proto**/
{

    switch ( status->Config->Source )
    {
       case FRNT_INLET: switch ( Inst_Config.Pneu.Frnt_Inlet.Type )
                        {
                         case  PP:
                         case  COC:
                         case  SS:
                         case  ACI:
                         case  SIMDIST:
                         case  CIS3:
                         case  CIS4:
                         case  VOLATILES:
                         case  PTV:        return TRUE;
                         case  MANUAL_PP:
                         case  MANUAL_COC:
                         case  MANUAL_ACI:
                         case  MANUAL_SS:
                         case  UNKNOWN_INLET:
                         case  NO_INLET:   return FALSE;
                         default:          return FALSE;
                        }

       case BACK_INLET: switch ( Inst_Config.Pneu.Back_Inlet.Type )
                        {
                         case  PP:
                         case  COC:
                         case  SS:
                         case  ACI:
                         case  SIMDIST:
                         case  CIS3:
                         case  CIS4:
                         case  VOLATILES:
                         case  PTV:        return TRUE;
                         case  MANUAL_PP:
                         case  MANUAL_ACI:
                         case  MANUAL_COC:
                         case  MANUAL_SS:
                         case  UNKNOWN_INLET:
                         case  NO_INLET:   return FALSE;
                         default:          return FALSE;
                        }

       case AUX_3:
       case AUX_4:
       case AUX_5:   return TRUE;


       case UNKNOWN_SOURCE:  return FALSE;
       default:              return FALSE;
    }

}

/**begin_proto**/

BIT8 VIFlowSourceChk ( pCOLUMN_STATUS status )

/**end_proto**/
{

    switch ( status->Config->Source )
    {
       case FRNT_INLET: if ( Inst_Status.Pneu.Frnt_Inlet.VI_Flow_Mode) return TRUE;
                        else return FALSE;

       case BACK_INLET: if ( Inst_Status.Pneu.Back_Inlet.VI_Flow_Mode ) return TRUE;
                        else return FALSE;

       default:              return FALSE ;
    }
}

/**begin_proto**/

BIT8 SourcePressureControlled ( pCOLUMN_STATUS status )

/**end_proto**/
{

    switch ( status->Config->Source )
    {
       case FRNT_INLET: if (
                            ( ((Inst_Config.Pneu.Frnt_Inlet.Type == PP ) || (Inst_Config.Pneu.Frnt_Inlet.Type == SIMDIST )
                               || (Inst_Config.Pneu.Frnt_Inlet.Type == ACI )) &&
                              ( Inst_Status.Pneu.Frnt_Inlet.Has_Column == FALSE ) )
                            || Inst_Status.Pneu.Frnt_Inlet.VI_Flow_Mode
                           ) return FALSE;
                         else       return TRUE;

       case BACK_INLET: if (
                            ( ((Inst_Config.Pneu.Back_Inlet.Type == PP ) || (Inst_Config.Pneu.Back_Inlet.Type == SIMDIST )
                               || (Inst_Config.Pneu.Back_Inlet.Type == ACI )) &&
                              ( Inst_Status.Pneu.Back_Inlet.Has_Column == FALSE ) )
                            || Inst_Status.Pneu.Back_Inlet.VI_Flow_Mode
                           ) return FALSE;
                         else       return TRUE;

       case AUX_3:
       case AUX_4:
       case AUX_5:   return TRUE;


       case UNKNOWN_SOURCE:
       default:              return TRUE;
    }
}


/**begin_proto**/

INT32 GetColumnPostPres ( pCOLUMN_STATUS status )

/**end_proto**/
{

    return ConvertPresIuToDisplay ( GetRampPostValue( status->Ramp_Info ), status->Ramp_Setpt.Ramp_Pres_Scaling );
}



/**begin_proto**/

INT32 DcGetColumnPostPres ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return ConvertPresIuToDcu ( GetRampPostValue( status->Ramp_Info ), status->Ramp_Setpt.Ramp_Pres_Scaling );
}


/**begin_proto**/

UI_ERR  SetColumnPostPres (INT32 pres, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT16 pres_iu;
     UI_ERR  error;

     if ( (error = ValidateColumnHeadPres( pres, status )) == OK )
     {
          pres_iu =  ConvertPresDisplayToIu ( pres, status->Ramp_Setpt.Ramp_Pres_Scaling );
          ChangeColumnPostPres( pres_iu, pres, status );
     }

     return error;
}



/**begin_proto**/

UI_ERR  DcSetColumnPostPres (INT32 post_value, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT16 pres_iu;
     INT32   pres;
     UI_ERR  error;


     pres_iu =  ConvertPresDcuToIu     ( post_value, status->Ramp_Setpt.Ramp_Pres_Scaling );
     pres    =  ConvertPresIuToDisplay ( pres_iu,    status->Ramp_Setpt.Ramp_Pres_Scaling );

     if ( (error = ValidateColumnHeadPres( pres, status )) == OK )
     {
          ChangeColumnPostPres( pres_iu, pres, status );
     }

     return error;
}

/**begin_proto**/

void ChangeColumnPostPres (U_INT16 pres_iu, INT32 pres, pCOLUMN_STATUS status )

/**end_proto**/
{


    if ( Inst_Config.Pneu.Column_1.Source == Inst_Config.Pneu.Column_2.Source )
    {
         SetRampPostValue( Inst_Status.Pneu.Column_1.Ramp_Info, pres_iu );
         SetRampPostValue( Inst_Status.Pneu.Column_2.Ramp_Info, pres_iu );
         LogSetptChange( COL12_POST_PRES, pres, (INT32)GetPresUnits() );
    }
    else
    {
         SetRampPostValue( status->Ramp_Info, pres_iu );
         LogSetptChange( status->Position == 1 ? COL1_POST_PRES : COL2_POST_PRES, pres, (INT32)GetPresUnits() );
    }

}


/**begin_proto**/

INT32 GetColumnPostFlow ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return ConvertFlowIuToDisplay ( GetRampPostValue( status->Ramp_Info ), status->Ramp_Setpt.Ramp_Flow_Scaling );
}



/**begin_proto**/

INT32 DcGetColumnPostFlow ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return ConvertFlowIuToDcu     ( GetRampPostValue( status->Ramp_Info ), status->Ramp_Setpt.Ramp_Flow_Scaling );
}


/**begin_proto**/

UI_ERR  SetColumnPostFlow (INT32 flow, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT32 flow_iu;
     UI_ERR  error;


     if ( (error = ValidateColumnVFlow( flow, status )) == OK)
     {
          flow_iu =  ConvertFlowDisplayToIu ( flow, status->Ramp_Setpt.Ramp_Flow_Scaling );
          ChangeColumnPostFlow ( flow_iu,  flow,  status );
     }
     return error;
}


/**begin_proto**/

UI_ERR  DcSetColumnPostFlow (INT32 flow, pCOLUMN_STATUS status )

/**end_proto**/
{

     U_INT32 flow_iu;
     INT32   flow_du;
     UI_ERR  error;

     flow_iu =  ConvertFlowDcuToIu     ( flow, status->Ramp_Setpt.Ramp_Flow_Scaling );
     flow_du =  ConvertFlowIuToDisplay ( flow,       status->Ramp_Setpt.Ramp_Flow_Scaling );

     if ( (error = ValidateColumnVFlow( flow_du, status )) == OK)
     {
          ChangeColumnPostFlow ( flow_iu,  flow_du,  status );
     }
     return error;
}

/**begin_proto**/

void ChangeColumnPostFlow (U_INT32 flow_iu, INT32 flow, pCOLUMN_STATUS status )

/**end_proto**/
{

    SetRampPostValue( status->Ramp_Info, flow_iu );

    if ( Inst_Config.Pneu.Column_1.Source == Inst_Config.Pneu.Column_2.Source )
    {
         LogSetptChange( COL12_POST_FLOW, flow, 0 );
    }
    else
    {
         LogSetptChange( status->Position == 1 ? COL1_POST_FLOW : COL2_POST_FLOW, flow, 0 );
    }


}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

GAS_TYPE GetColumnGasType ( pCOLUMN_STATUS status )

/**end_proto**/
{

     switch ( status->Config->Source )
     {

         case FRNT_INLET:  return Inst_Config.Pneu.Frnt_Inlet.Gas_Type;
         case BACK_INLET:  return Inst_Config.Pneu.Back_Inlet.Gas_Type;
         case AUX_3:       return Inst_Config.Pneu.Aux_3.Gas_Type;
         case AUX_4:       return Inst_Config.Pneu.Aux_4.Gas_Type;
         case AUX_5:       return Inst_Config.Pneu.Aux_5.Gas_Type;
         default:          return UNKNOWN_GAS;
     }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

ON_OFF GetColumnSourceState ( pCOLUMN_STATUS status )

/**end_proto**/
{
     switch ( status->Config->Source )
     {
         case FRNT_INLET:  return GetInletState( &Inst_Status.Pneu.Frnt_Inlet );
         case BACK_INLET:  return GetInletState( &Inst_Status.Pneu.Back_Inlet );
         case AUX_3:       return GetAuxState  ( &Inst_Status.Pneu.Aux.Aux_3 );
         case AUX_4:       return GetAuxState  ( &Inst_Status.Pneu.Aux.Aux_4 );
         case AUX_5:       return GetAuxState  ( &Inst_Status.Pneu.Aux.Aux_5 );
         default:          return OFF;
     }
}

/**begin_proto**/

UI_ERR SetColumnSourceState ( pCOLUMN_STATUS status, ON_OFF state )

/**end_proto**/
{
   BIT8 setpt_changed;
   setpt_changed = ( GetColumnSourceState( status ) != state );
   ChangeColumnSourceState( status, state );

   if ( setpt_changed )
   {
      if ( state == ON )
      {
          if ( SourcePressureControlled( status ) )
          {
              LogSetptChange( status->Position == 1 ? COL1_PRES_ON : COL2_PRES_ON, 0, 0 );
          }
          else
          {
              LogSetptChange( status->Position == 1 ? COL1_FLOW_ON : COL2_FLOW_ON, 0, 0 );
          }
      }
      else
      {
          if ( SourcePressureControlled( status ) )
          {
              LogSetptChange( status->Position == 1 ? COL1_PRES_OFF : COL2_PRES_OFF, 0, 0 );
          }
          else
          {
              LogSetptChange( status->Position == 1 ? COL1_FLOW_OFF : COL2_FLOW_OFF, 0, 0 );
          }
      }
   }

   return OK;
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ChangeColumnSourceState ( pCOLUMN_STATUS status, ON_OFF state )

/**end_proto**/
{

     switch ( status->Config->Source )
     {
         case FRNT_INLET:  ChangeInletState( state, &Inst_Status.Pneu.Frnt_Inlet );
                           break;
         case BACK_INLET:  ChangeInletState( state, &Inst_Status.Pneu.Back_Inlet );
                           break;
         case AUX_3:       ChangeAuxState  ( state, &Inst_Status.Pneu.Aux.Aux_3 );
                           break;
         case AUX_4:       ChangeAuxState  ( state, &Inst_Status.Pneu.Aux.Aux_4 );
                           break;
         case AUX_5:       ChangeAuxState  ( state, &Inst_Status.Pneu.Aux.Aux_5 );
                           break;
     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

INT32 GetSourceMaxPres( pCOLUMN_STATUS status )

/**end_proto**/
{
     switch ( status->Config->Source )
     {
         case FRNT_INLET:  return GetInletMaxPres( &Inst_Status.Pneu.Frnt_Inlet );
         case BACK_INLET:  return GetInletMaxPres( &Inst_Status.Pneu.Back_Inlet );
         case AUX_3:       return GetAuxMaxPres  ( &Inst_Status.Pneu.Aux.Aux_3 );
         case AUX_4:       return GetAuxMaxPres  ( &Inst_Status.Pneu.Aux.Aux_4 );
         case AUX_5:       return GetAuxMaxPres  ( &Inst_Status.Pneu.Aux.Aux_5 );
         default:          return 0;
     }
}

/**begin_proto**/

U_INT16 GetSourceMaxPresIu( pCOLUMN_STATUS status )

/**end_proto**/
{
     switch ( status->Config->Source )
     {
         case FRNT_INLET:  return GetInletMaxPresIu( &Inst_Status.Pneu.Frnt_Inlet, status->Dcm2_Per_IU );
         case BACK_INLET:  return GetInletMaxPresIu( &Inst_Status.Pneu.Back_Inlet, status->Dcm2_Per_IU );
         case AUX_3:       return GetAuxMaxPresIu  ( &Inst_Status.Pneu.Aux.Aux_3,  status->Dcm2_Per_IU );
         case AUX_4:       return GetAuxMaxPresIu  ( &Inst_Status.Pneu.Aux.Aux_4,  status->Dcm2_Per_IU );
         case AUX_5:       return GetAuxMaxPresIu  ( &Inst_Status.Pneu.Aux.Aux_5,  status->Dcm2_Per_IU );
         default:          return 0;
     }
}

/**begin_proto**/

U_INT16 GetSourceRealMaxPresIu( pCOLUMN_STATUS status )

/**end_proto**/
{
     switch ( status->Config->Source )
     {
         case FRNT_INLET:  return GetInletRealMaxPresIu( &Inst_Status.Pneu.Frnt_Inlet, status->Dcm2_Per_IU );
         case BACK_INLET:  return GetInletRealMaxPresIu( &Inst_Status.Pneu.Back_Inlet, status->Dcm2_Per_IU );
         case AUX_3:       return GetAuxRealMaxPresIu  ( &Inst_Status.Pneu.Aux.Aux_3,  status->Dcm2_Per_IU );
         case AUX_4:       return GetAuxRealMaxPresIu  ( &Inst_Status.Pneu.Aux.Aux_4,  status->Dcm2_Per_IU );
         case AUX_5:       return GetAuxRealMaxPresIu  ( &Inst_Status.Pneu.Aux.Aux_5,  status->Dcm2_Per_IU );
         default:          return 0;
     }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

INT32 GetSourceMaxFlow( pCOLUMN_STATUS status, U_INT16 temp )

/**end_proto**/
{

     U_INT32 max_flow;
     U_INT32 source_max_flow;

     if ( status->Config->Defined )
     {
         /* defined columns are always pressure controlled */
         /* errant case of one defined, one undefined col will come here */

           max_flow = CalcVFlow( status,
                               /*GetCurrentOvenTemp(),*/
                                 temp,
                                 GetSourceMaxPresIu(status),
                                 GetNtpOutletPressure(status) );

           switch ( GetColSourceType( status ) )
           {
              case SS_INLET:
              case PP_INLET:
              case ACI_INLET:
              case SIMDIST_INLET:
              case CIS3_INLET:
              case CIS4_INLET:
              case VOLATILES_INLET:
               if ( max_flow > (source_max_flow = GetSourceMaxFlowIu( status, temp )) )
               {
                    max_flow =  source_max_flow;
               }
               break;
           }
     }
     else
     {
         if (( GetColSourceType( status ) == PP_INLET ) || ( GetColSourceType( status ) == SIMDIST_INLET )
                                                        || ( GetColSourceType( status ) == ACI_INLET ))
         {
             if ( Inst_Config.Pneu.Column_1.Source == Inst_Config.Pneu.Column_2.Source )
             {
                 /* if two cols on same inlet, divide flow by two */
                 if ( status->Config->Source == FRNT_INLET )
                 {
                     max_flow = GetInletMaxFlowIu( &Inst_Status.Pneu.Frnt_Inlet, status->IU_Scaling ) / 2 ;
                 }
                 else
                 {
                     max_flow = GetInletMaxFlowIu( &Inst_Status.Pneu.Back_Inlet, status->IU_Scaling ) / 2 ;
                 }
             }
             else
             {
                 if ( status->Config->Source == FRNT_INLET )
                 {
                     max_flow = GetInletMaxFlowIu( &Inst_Status.Pneu.Frnt_Inlet, status->IU_Scaling );
                 }
                 else
                 {
                     max_flow = GetInletMaxFlowIu( &Inst_Status.Pneu.Back_Inlet, status->IU_Scaling );
                 }
             }
         }
         else
         {
                /* undefined column on pressure controlled inlet,  */
                /* when this happens, a flow line should not appear! */

              max_flow = 0;
         }
     }


     return ConvertFlowIuToDisplay( max_flow, status->IU_Scaling );

}

/**begin_proto**/

INT32 KbdGetSourceMaxFlow( pCOLUMN_STATUS status )

/**end_proto**/
{
   return GetSourceMaxFlow (status, GetCurrentOvenTemp());
}


/**begin_proto**/

U_INT32 GetSourceMaxFlowIu( pCOLUMN_STATUS status, U_INT16 temp )

/**end_proto**/
{

     switch ( status->Config->Source )
     {
         case FRNT_INLET:  return GetInletMaxFlowIu( &Inst_Status.Pneu.Frnt_Inlet, status->IU_Scaling );
         case BACK_INLET:  return GetInletMaxFlowIu( &Inst_Status.Pneu.Back_Inlet, status->IU_Scaling );
         case AUX_3:       return CalcVFlow ( status,
                                              /* GetCurrentOvenTemp(),  */
                                              temp,
                                              Inst_Status.Pneu.Aux.Aux_3.P_Sensor_Range,
                                              GetNtpOutletPressure(status) );
         case AUX_4:       return CalcVFlow ( status,
                                              /* GetCurrentOvenTemp(), */
                                              temp,
                                              Inst_Status.Pneu.Aux.Aux_4.P_Sensor_Range,
                                              GetNtpOutletPressure(status) );
         case AUX_5:       return CalcVFlow ( status,
                                              /* GetCurrentOvenTemp(), */
                                              temp,
                                              Inst_Status.Pneu.Aux.Aux_5.P_Sensor_Range,
                                              GetNtpOutletPressure(status) );
         default:          return 0;
     }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

CALIB_MODE GetColumnCalibMode ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return status->Config->Calib.Mode;
}


/**begin_proto**/

UI_ERR SetColumnCalibMode ( pCOLUMN_STATUS status, CALIB_MODE mode )

/**end_proto**/
{
    UI_ERR error;

    if ((error = ValidateColCalibMode( mode ))!= OK ) return error;

    /* if mode isn't changing, leave it alone */
    if ( mode == status->Config->Calib.Mode ) return OK;

    LockResource( &Inst_Status.Pneu.Resource_Lock );

    ChangeColumnCalibMode ( status, mode );

    ReleaseResource( &Inst_Status.Pneu.Resource_Lock );

    return OK;
}



/**begin_proto**/

void   ChangeColumnCalibMode ( pCOLUMN_STATUS status, CALIB_MODE mode )

/**end_proto**/
{

      /* see if we are diabling or reenabling a calib, otherwise blow away the previous calib */

    if  (( mode == UNCALIBRATED ) ||

      /* look to see if we are just trying to re-enable a previous calib */
        ( (( status->Config->Calib.Mode == UNCALIBRATED ) &&
          (( status->Config->Calib.Calib_Length != 0 ) &&
           ( status->Config->Calib.Calib_Diam != 0 )   &&
           ( !DateIsUninitialized( status->Config->Calib.Date )))) &&

               /* they want to re-enable it, is the previous calib still valid ? */
           ( (( mode == LENGTH_ONLY )  &&
              ( ValidateCalibLength( status, status->Config->Calib.Calib_Length ) == OK ) &&
              ( status->Config->Calib.Calib_Diam   == status->Config->Diam   ))              ||

             (( mode == DIAM_ONLY   ) &&
              ( ValidateCalibDiam( status, status->Config->Calib.Calib_Diam ) == OK ) &&
              ( status->Config->Calib.Calib_Length == status->Config->Length ))              ||

             (( mode == LENGTH_AND_DIAM )  &&
              ( ValidateCalibLength( status, status->Config->Calib.Calib_Length ) == OK ) &&
              ( ValidateCalibDiam( status, status->Config->Calib.Calib_Diam ) == OK ) ))))
    {
         if ( mode == UNCALIBRATED )
            LogSetptChange( status->Position == 1 ? COL1_CAL_OFF : COL2_CAL_OFF, 0, 0 );
         else
            LogSetptChange( status->Position == 1 ? COL1_CAL_ON  : COL2_CAL_ON,  0, 0 );
    }
    else
    {
         LogSetptChange( status->Position == 1 ? COL1_CAL_OFF : COL2_CAL_OFF, 0, 0 );
    }

    UpdateColumnCalibMode( status, mode );
}


/**begin_proto**/

void   UpdateColumnCalibMode ( pCOLUMN_STATUS status, CALIB_MODE mode )

/**end_proto**/
{

      /* see if we are diabling or reenabling a calib, otherwise blow away the previous calib */

    if  (( mode == UNCALIBRATED ) ||

      /* look to see if we are just trying to re-enable a previous calib */
        ( (( status->Config->Calib.Mode == UNCALIBRATED ) &&
          (( status->Config->Calib.Calib_Length != 0 ) &&
           ( status->Config->Calib.Calib_Diam != 0 )   &&
           ( !DateIsUninitialized( status->Config->Calib.Date )))) &&

               /* they want to re-enable it, is the previous calib still valid ? */
           ( (( mode == LENGTH_ONLY )  &&
              ( ValidateCalibLength( status, status->Config->Calib.Calib_Length ) == OK ) &&
              ( status->Config->Calib.Calib_Diam   == status->Config->Diam   ))              ||

             (( mode == DIAM_ONLY   ) &&
              ( ValidateCalibDiam( status, status->Config->Calib.Calib_Diam ) == OK ) &&
              ( status->Config->Calib.Calib_Length == status->Config->Length ))              ||

             (( mode == LENGTH_AND_DIAM )  &&
              ( ValidateCalibLength( status, status->Config->Calib.Calib_Length ) == OK ) &&
              ( ValidateCalibDiam( status, status->Config->Calib.Calib_Diam ) == OK ) ))))
    {
         status->Config->Calib.Mode = mode;
    }
    else
    {
         status->Config->Calib.Mode = mode;
         status->Config->Calib.Measured_Flow = 0;
         status->Config->Calib.Holdup_Time   = 0;
         status->Config->Calib.Calib_Length  = 0;
         status->Config->Calib.Calib_Diam    = 0;
#if 0
         StrNCpy( (BIT8 *)status->Config->ID_String, (BIT8 *)" ", 1 );
#endif
         InitializeDateTime( &status->Config->Calib.Date );

    }

    ReconfigurePneu();


}


/**begin_proto**/

INT32 GetColumnCalibHoldTime ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return MilliSecsToRetTime( status->Config->Calib.Holdup_Time );
}

/**begin_proto**/

INT32 DcGetColumnCalibHoldTime ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return MilliSecsToRetTime( status->Config->Calib.Holdup_Time );
}

/**begin_proto**/

UI_ERR ValidateCalibHoldTime ( INT32 time )

/**end_proto**/
{
    return ValidateRetTime ( time );
}


/**begin_proto**/

UI_ERR SetColumnCalibHoldTime ( pCOLUMN_STATUS status, INT32 time )

/**end_proto**/
{
    UI_ERR error;

    if ( (error = ValidateCalibHoldTime ( time ) ) != OK ) return error;
    if ( time == 0 ) return PARAM_TOO_SMALL;

    LockResource( &Inst_Status.Pneu.Resource_Lock );

    error = ChangeColumnCalibHoldTime( status, RetTimeToMilliSecs( time ) );

    ReleaseResource( &Inst_Status.Pneu.Resource_Lock );

    return error;
}


/**begin_proto**/

UI_ERR DcSetColHoldTime ( pCOLUMN_STATUS status, INT32 time )

/**end_proto**/
{
    UI_ERR error;

    if ( (error = ValidateCalibHoldTime ( time ) ) != OK ) return error;

    error = ChangeColumnCalibHoldTime( status, RetTimeToMilliSecs( time ) );

    return error;
}


/**begin_proto**/

UI_ERR ChangeColumnCalibHoldTime ( pCOLUMN_STATUS status, INT32 time )

/**end_proto**/
{
    UI_ERR error;

    error = INVALID_PARAM;

    status->Config->Calib.Holdup_Time   = time;

    if (( status->Config->Calib.Mode == DIAM_ONLY ) && ( time != 0 ))
    {
          status->Config->Calib.Measured_Flow = 0;
          error = CalibrateColumnDiameter( status );
    }
    else if (( status->Config->Calib.Mode == LENGTH_ONLY ) && ( time != 0 ))
    {
          status->Config->Calib.Measured_Flow = 0;
          error = CalibrateColumnLength( status );
    }
    else if (( status->Config->Calib.Mode == LENGTH_AND_DIAM ) &&
             ( time != 0 ) && ( status->Config->Calib.Measured_Flow != 0 ))
    {
          error = CalColLengthAndDiam( status );
    }

    return error;
}



/**begin_proto**/

INT32 GetColumnCalibMeasFlow ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return ConvertFlowIuToDisplay( status->Config->Calib.Measured_Flow, status->IU_Scaling );
}

/**begin_proto**/

INT32 DcGetColMeasFlow ( pCOLUMN_STATUS status )

/**end_proto**/
{
    return ConvertFlowIuToDcu( status->Config->Calib.Measured_Flow, status->IU_Scaling );
}



/**begin_proto**/

UI_ERR SetColumnCalibMeasFlow ( pCOLUMN_STATUS status, INT32 flow )

/**end_proto**/
{
    UI_ERR error;
    U_INT32 flow_iu;

    if ( (error = ValidateColumnVFlow( flow, status )) != OK) return error;
    if ( flow == 0 ) return PARAM_TOO_SMALL;

    LockResource( &Inst_Status.Pneu.Resource_Lock );

    flow_iu = ConvertFlowDisplayToIu( flow, status->IU_Scaling );

    ReleaseResource( &Inst_Status.Pneu.Resource_Lock );

    return ChangeColMeasFlow ( status, flow_iu );

}


/**begin_proto**/

UI_ERR DcSetColMeasFlow ( pCOLUMN_STATUS status, INT32 flow_dcu )

/**end_proto**/
{
    UI_ERR error;
    U_INT32 flow_iu;
    U_INT32 flow;

    flow_iu = ConvertFlowDcuToIu    ( flow_dcu, status->IU_Scaling );
    flow    = ConvertFlowIuToDisplay( flow_iu,  status->IU_Scaling );

    if ( (error = ValidateColumnVFlow( flow, status )) != OK) return error;

    return ChangeColMeasFlow ( status, flow_iu );

}


/**begin_proto**/

UI_ERR ChangeColMeasFlow ( pCOLUMN_STATUS status, U_INT32 flow )

/**end_proto**/
{

    UI_ERR error;

    error = OK;

    status->Config->Calib.Measured_Flow = flow;

    if (( status->Config->Calib.Mode == DIAM_ONLY ) && ( flow != 0 ))
    {
          status->Config->Calib.Holdup_Time = 0;
          error = CalibrateColumnDiameter( status );
    }
    else if (( status->Config->Calib.Mode == LENGTH_ONLY ) && ( flow != 0 ))
    {
          status->Config->Calib.Holdup_Time = 0;
          error = CalibrateColumnLength( status );
    }
    else if (( status->Config->Calib.Mode == LENGTH_AND_DIAM ) &&
             ( flow != 0 ) && ( status->Config->Calib.Holdup_Time != 0 ))
    {
          error = CalColLengthAndDiam( status );
    }

    return error;
}



/**begin_proto**/

INT32 GetColumnCalibLength ( pCOLUMN_STATUS status )

/**end_proto**/
{
     return status->Config->Calib.Calib_Length;
}

/**begin_proto**/

INT32 GetColumnCalibDiam ( pCOLUMN_STATUS status )

/**end_proto**/
{
     return status->Config->Calib.Calib_Diam;
}

/**begin_proto**/

INT32 DcGetColumnCalibMode ( pCOLUMN_STATUS status )

/**end_proto**/
{
     return (INT32)status->Config->Calib.Mode;
}

/**begin_proto**/

UI_ERR ValidateColCalibMode( CALIB_MODE mode )

/**end_proto**/
{

    switch ( mode )
    {
       case UNCALIBRATED:
       case LENGTH_ONLY:
       case DIAM_ONLY:
       case LENGTH_AND_DIAM:  break;

       default: return INVALID_PARAM;
    }

    return OK;
}


/**begin_proto**/

UI_ERR DcSetColCalibMode( pCOLUMN_STATUS status, CALIB_MODE mode )

/**end_proto**/
{
    UI_ERR error;

    if ((error = ValidateColCalibMode( mode ))!= OK ) return error;

    ChangeColumnCalibMode( status, mode );

    return OK;
}



/**begin_proto**/

DATETIME GetColumnCalibDate ( pCOLUMN_STATUS status )

/**end_proto**/
{
     return status->Config->Calib.Date;
}

/**begin_proto**/

INT32 DcGetColCalibDate( pCOLUMN_STATUS status )

/**end_proto**/
{
   return SecondsSince1980( status->Config->Calib.Date );
}


/**begin_proto**/

INT32 DcGetColCalibLength ( pCOLUMN_STATUS status )

/**end_proto**/
{
     return status->Config->Calib.Calib_Length;
}

/**begin_proto**/

INT32 DcGetColCalibDiam ( pCOLUMN_STATUS status )

/**end_proto**/
{
     return status->Config->Calib.Calib_Diam;
}







/**begin_proto**/

UI_ERR SetColumnCalibDiam( pCOLUMN_STATUS status, INT32 diam )

/**end_proto**/
{

    UI_ERR error;

    if ((error = ValidateCalibDiam( status, diam )) != OK ) return error;

    UpdateColumnCalibDiam( status, diam );

    LogSetptChange( status->Position == 1 ? COL1_CAL_DIAM: COL2_CAL_DIAM,status->Config->Calib.Calib_Diam,   0 );

    return OK;
}

/**begin_proto**/

void UpdateColumnCalibDiam( pCOLUMN_STATUS status, INT32 diam )

/**end_proto**/
{
    status->Config->Calib.Calib_Diam = diam;

    ReconfigurePneu();
}


/**begin_proto**/

UI_ERR SetColumnCalibLength( pCOLUMN_STATUS status, INT32 length )

/**end_proto**/
{
    UI_ERR error;

    if ((error = ValidateCalibLength( status,  length )) != OK ) return error;

    UpdateColumnCalibLength( status, length );

    LogSetptChange( status->Position == 1 ? COL1_CAL_LEN : COL2_CAL_LEN, status->Config->Calib.Calib_Length, 0 );

    return OK;
}


/**begin_proto**/

void UpdateColumnCalibLength( pCOLUMN_STATUS status, INT32 length )

/**end_proto**/
{

    status->Config->Calib.Calib_Length = length;

    ReconfigurePneu();

}


/**begin_proto**/

UI_ERR DcAcceptCalibMode( pCOLUMN_STATUS status, INT32 mode )

/**end_proto**/
{

    UI_ERR error;

    if ((error = ValidateColCalibMode( (CALIB_MODE) mode )) != OK ) return error;

    status->Config->Calib.Mode = (CALIB_MODE) mode;

    if ( (CALIB_MODE) mode == UNCALIBRATED ) InitializeDateTime( &status->Config->Calib.Date );

    ReconfigurePneu();

    return OK;
}

/**begin_proto**/

UI_ERR DcAcceptColMeasFlow( pCOLUMN_STATUS status, INT32 flow )

/**end_proto**/
{
    U_INT32 flow_iu;

    flow_iu = ConvertFlowDcuToIu     ( flow,    status->IU_Scaling );

    status->Config->Calib.Measured_Flow = flow_iu;

    return OK;
}


/**begin_proto**/

UI_ERR DcAcceptColHoldTime( pCOLUMN_STATUS status, INT32 time )

/**end_proto**/
{
    status->Config->Calib.Holdup_Time = RetTimeToMilliSecs( time );

    return OK;
}




/**begin_proto**/

UI_ERR DcAcceptCalibDate( pCOLUMN_STATUS status, INT32 seconds )

/**end_proto**/
{

    status->Config->Calib.Date = TimeFromSeconds( seconds );

    ReconfigurePneu();

    return OK;
}

/**begin_proto**/

UI_ERR DcAcceptCalibDiam( pCOLUMN_STATUS status, INT32 diam )

/**end_proto**/
{

    UI_ERR error;

    if ((error = ValidateCalibDiam( status, diam )) != OK ) return error;

    UpdateColumnCalibDiam( status, diam );

    LogSetptChange( status->Position == 1 ? COL1_CAL_DIAM: COL2_CAL_DIAM,status->Config->Calib.Calib_Diam,   0 );

    return OK;
}


/**begin_proto**/

UI_ERR DcAcceptCalibLength( pCOLUMN_STATUS status, INT32 length )

/**end_proto**/
{
    UI_ERR error;

    if ((error = ValidateCalibLength( status, length )) != OK ) return error;

    UpdateColumnCalibLength( status, length );

    LogSetptChange( status->Position == 1 ? COL1_CAL_LEN : COL2_CAL_LEN, status->Config->Calib.Calib_Length, 0 );

    return OK;
}
















/**begin_proto**/

BIT8 IsColumnCalibrated ( pCOLUMN_STATUS status )

/**end_proto**/
{
     return ( status->Config->Calib.Mode != UNCALIBRATED ) &&
            ( status->Config->Calib.Calib_Length != 0 ) &&
            ( status->Config->Calib.Calib_Diam != 0 )   &&
            ( !DateIsUninitialized( status->Config->Calib.Date ) );
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

UI_ERR CalibrateColumnDiameter( pCOLUMN_STATUS status )

/**end_proto**/
{

     UI_ERR error;

     error = OK;

     if ( (error = OkToCalibColumn( status )) != OK ) return error;

     if ( status->Config->Calib.Holdup_Time == 0 )
     {
          error = CalibDiamFromFlow( status );
     }
     else
     {
          error = CalibDiamFromTime( status );
     }

     if ( error == OK ) ReconfigurePneu();

     return error;
}

/**begin_proto**/

UI_ERR CalibrateColumnLength( pCOLUMN_STATUS status )

/**end_proto**/
{

     UI_ERR error;

     error = OK;

     if ( (error = OkToCalibColumn( status )) != OK ) return error;

     if ( status->Config->Calib.Holdup_Time == 0 )
     {
          error = CalibLengthFromFlow( status );
     }
     else
     {
          error = CalibLengthFromTime( status );
     }

     if ( error == OK ) ReconfigurePneu();

     return error;
}

/**begin_proto**/

UI_ERR CalColLengthAndDiam( pCOLUMN_STATUS status )

/**end_proto**/
{

     UI_ERR error;

     if ( (error = OkToCalibColumn( status )) != OK ) return error;

     error = CalibLengthAndDiam( status );

     return error;
}


/**begin_proto**/

UI_ERR OkToCalibColumn( pCOLUMN_STATUS status )

/**end_proto**/
{
   /* must be isothermal */
   if ( GetRampRate( Oven_Table.ramp_info, 1 ) != 0 ) return INVALID_OP;

   /* gotta know wat the column is */
   if ( ! status->Config->Defined ) return NOT_ALLOWED;

   /* column source must be on */
   if (( GetColumnSourceState(status) == OFF ) || ( status->NTP_Adjusted_Current_Pressure == 0 ))
   {
       return NOT_COMPATIBLE;
   }

   return OK;

}


/**begin_proto**/

void UpdateColumnPostValues( void )

/**end_proto**/
{

    pCOLUMN_STATUS status;
    void *ramp_info;

    U_INT16 P_25C;
    U_INT16 oven_temp;
    U_INT16 pressure;

    status    = &Inst_Status.Pneu.Column_1;
    ramp_info = status->Ramp_Info;

    if (( SourcePressureControlled ( status ) ) &&
        ( status->Wkfile->Control_Mode == CONST_FLOW ) &&
        ( status->Config->Defined == FALSE ))
    {
        oven_temp = GET_OVEN_INIT_TEMP;

        P_25C = QuadWordMultiplyDivide( status->Ramp_Setpt.Head_Pressure,
                                        status->Ramp_Setpt.Ramp_Pres_Scaling,
                                        status->Dcm2_Per_IU );

        if (status->Config->Vacuum_Comp == ON)
        {
            pressure = CalcPiFromPrevWVC( status, oven_temp, P_25C );
        }
        else
        {
            pressure = CalcPiFromPrevWOVC( status, oven_temp, P_25C );
        }

        SetRampPostValue( ramp_info, QuadWordMultiplyDivide( pressure,
                                                             status->Dcm2_Per_IU,
                                                             status->Ramp_Setpt.Ramp_Pres_Scaling ) );

    }
    else
    {
        SetRampPostValue( ramp_info, GetRampInitValue( ramp_info ) );
    }





    status    = &Inst_Status.Pneu.Column_2;
    ramp_info = status->Ramp_Info;

    if (( SourcePressureControlled ( status ) ) &&
        ( status->Wkfile->Control_Mode == CONST_FLOW ) &&
        ( status->Config->Defined == FALSE ))
    {
        oven_temp = GET_OVEN_INIT_TEMP;

        P_25C = QuadWordMultiplyDivide( status->Ramp_Setpt.Head_Pressure,
                                        status->Ramp_Setpt.Ramp_Pres_Scaling,
                                        status->Dcm2_Per_IU );

        if (status->Config->Vacuum_Comp == ON)
        {
            pressure = CalcPiFromPrevWVC( status, oven_temp, P_25C );
        }
        else
        {
            pressure = CalcPiFromPrevWOVC( status, oven_temp, P_25C );
        }

        SetRampPostValue( ramp_info, QuadWordMultiplyDivide( pressure,
                                                             status->Dcm2_Per_IU,
                                                             status->Ramp_Setpt.Ramp_Pres_Scaling ) );

    }
    else
    {
        SetRampPostValue( ramp_info, GetRampInitValue( ramp_info ) );
    }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

UI_ERR EstimatedMinimumPeakWidth ( pCOLUMN_STATUS status, INT32 *peak_width )

/**end_proto**/
{

      float avg_velocity;
      float opening;
      float width;

      if ( status->Config->Defined == FALSE )     return INVALID_OP;
      if ( GetColumnSourceState( status) != ON )  return INVALID_OP;

      avg_velocity = (float)  CalcUavg(status,
                                       GetOvenInitTemp(),
                                       CalcColumnInitP( status ),
                                       GetNtpOutletPressure( status )) / (float) status->Vel_IU_Scaling;

      if ( avg_velocity == 0 ) return INVALID_OP;

      opening = (((float)status->Config->Diam - 2 * (float)status->Config->Film_Thickness/COLUMN_FILM_SCALING) * 1e-4 );

      width =   3.53 * ( sqrt( status->Config->Length ) / avg_velocity ) *
        sqrt( 0.6 / avg_velocity + pow( opening / 2, 2 ) * avg_velocity / 2.4 );

      /* convert from sec to 1000ths min */

      *peak_width =  (INT32) ( 1000.0 * width / 60.0 );

      return OK;
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void SourceSetptChanged( SOURCE_CONNECTION source )

/**end_proto**/
{
     ResetSigPathState();  /* so if SIGx="a_pneu_signal" & col defn chgs, the plot scaling changes too ! */
                           /* without above line scaling updated ONLY at end of run; needs immediate too */
     switch ( source )
     {
         case FRNT_INLET:  TwiddleInletSetptChangedFlag ( &Inst_Status.Pneu.Frnt_Inlet );
                           break;
         case BACK_INLET:  TwiddleInletSetptChangedFlag ( &Inst_Status.Pneu.Back_Inlet );
                           break;
         case AUX_3:       TwiddleAuxSetptChangedFlag ( &Inst_Status.Pneu.Aux.Aux_3 );
                           break;
         case AUX_4:       TwiddleAuxSetptChangedFlag ( &Inst_Status.Pneu.Aux.Aux_4 );
                           break;
         case AUX_5:       TwiddleAuxSetptChangedFlag ( &Inst_Status.Pneu.Aux.Aux_5 );
                           break;
     }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

INT32 GetColumnInitPres( pCOLUMN_STATUS status )

/**end_proto**/
{

      BIT8    epc_source;

      epc_source = EpcSource( status );

    if ( epc_source && ( GetColumnSourceState ( status ) != ON ))
    {
       return 0;
    }

    return ConvertPresIuToDisplay ( CalcColumnInitP( status ), status->Dcm2_Per_IU );

}


/**begin_proto**/

INT32 GetColumnInitFlow( pCOLUMN_STATUS status )

/**end_proto**/
{
   U_INT16 pres;
   U_INT16 temp;
   U_INT16 Po;
      BIT8    epc_source;

      epc_source = EpcSource( status );

    if ( epc_source && ( GetColumnSourceState ( status ) != ON ))
    {
       return 0;
    }

    pres = CalcColumnInitP( status );
    temp = GetOvenInitTemp();
    Po   = GetNtpOutletPressure( status );

    return ConvertFlowIuToDisplay( CalcVFlow( status, temp, pres, Po ), status->IU_Scaling );

}


/**begin_proto**/

INT32 GetColumnInitVel ( pCOLUMN_STATUS status )

/**end_proto**/
{
   U_INT16 pres;
   U_INT16 temp;
   U_INT16 Po;
      BIT8    epc_source;

      epc_source = EpcSource( status );

    if ( epc_source && ( GetColumnSourceState ( status ) != ON ))
    {
       return 0;
    }

    pres = CalcColumnInitP( status );
    temp = GetOvenInitTemp();
    Po   = GetNtpOutletPressure( status );

    return ConvertVelIuToDisplay( CalcUavg( status, temp, pres, Po ), status->Vel_IU_Scaling );

}



/**begin_proto**/
#pragma SECTION UNDO
/**end_proto**/
